Initial set of Fabric switch test cases

Change-Id: I86fd2b67d3b773aa496f5ef61f1e1fdf51fd9925
diff --git a/Fabric/Utilities/accton/accton_util.py b/Fabric/Utilities/accton/accton_util.py
new file mode 100755
index 0000000..0f32e76
--- /dev/null
+++ b/Fabric/Utilities/accton/accton_util.py
@@ -0,0 +1,2210 @@
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+import logging
+
+from oftest import config
+import oftest.base_tests as base_tests
+import ofp
+import time
+from oftest.testutils import *
+from oftest.parse import parse_ipv6
+
+from ncclient import manager
+import ncclient
+
+OFDPA_GROUP_TYPE_SHIFT=28
+OFDPA_VLAN_ID_SHIFT   =16
+OFDPA_TUNNEL_ID_SHIFT =12
+OFDPA_TUNNEL_SUBTYPE_SHIFT=10
+
+#VLAN_TABLE_FLAGS
+VLAN_TABLE_FLAG_ONLY_UNTAG=1
+VLAN_TABLE_FLAG_ONLY_TAG  =2
+VLAN_TABLE_FLAG_ONLY_BOTH =3
+VLAN_TABLE_FLAG_ONLY_STACKED=5
+VLAN_TABLE_FLAG_PRIORITY=6
+VLAN_TABLE_FLAG_ONLY_UNTAG_PRIORITY=7
+VLAN_TABLE_FLAG_ONLY_POP_VLAN=8
+
+PORT_FLOW_TABLE=0
+VLAN_FLOW_TABLE=10
+VLAN_1_FLOW_TABLE=11
+MPLS_L2_PORT_FLOW_TABLE=13
+MPLS_L2_PORT_DSCP_TRUST_FLOW_TABLE=15
+MPLS_L2_PORT_PCP_TRUST_FLOW_TABLE=16
+TERMINATION_FLOW_TABLE=20
+MPLS_TYPE_FLOW_TABLE=29
+UCAST_ROUTING_FLOW_TABLE=30
+MCAST_ROUTING_FLOW_TABLE=40
+BRIDGE_FLOW_TABLE=50
+ACL_FLOW_TABLE=60
+EGRESS_TPID_FLOW_TABLE = 235
+
+ONF_EXPERIMENTER_ID = 0x4F4E4600
+
+EGRESS_VLAN_FLOW_TABLE=210
+EGRESS_VLAN_1_FLOW_TABLE=211
+EGRESS_MAINTENANCE_POINT_FLOW_TABLE=226
+EGRESS_DSCP_TABLE=230
+EGRESS_TPID_TABLE=235
+EGRESS_SOURCE_MAC_LEARNING_TABLE=254
+
+def convertIP4toStr(ip_addr):
+    a=(ip_addr&0xff000000)>>24
+    b=(ip_addr&0x00ff0000)>>16
+    c=(ip_addr&0x0000ff00)>>8
+    d=(ip_addr&0x000000ff)
+    return str(a)+"."+str(b)+"."+str(c)+"."+str(d)
+
+def convertMACtoStr(mac):
+    if not isinstance(mac, list):
+        assert(0)
+
+    return ':'.join(['%02X' % x for x in mac])
+
+def getSwitchCpuMACFromDPID(dpid):
+    str_datapath_id_f= "{:016x}".format(dpid)
+    str_datapath_id=':'.join([str_datapath_id_f[i:i+2] for i in range(0, len(str_datapath_id_f), 2)])
+    switch_cpu_mac_str=str_datapath_id[6:]
+    switch_cpu_mac = switch_cpu_mac_str.split(":")
+    switch_cpu_mac=[int(switch_cpu_mac[i],16) for i in range(0, len(switch_cpu_mac))]
+
+    return switch_cpu_mac_str, switch_cpu_mac
+
+def DumpGroup(stats, verify_group_stats, always_show=True):
+    if(len(stats) > len(verify_group_stats)):
+        min_len = len(verify_group_stats)
+        print "Stats Len is not the same, stats>verify_group_stats"
+    if(len(stats)< len(verify_group_stats)):
+        min_len = len(stats)
+        print "Stats Len is not the same, stats<verify_group_stats"
+    else:
+        min_len = len(stats)
+
+    print "\r\n"
+    for i in range(min_len):
+        gs = stats[i]
+        gv = verify_group_stats[i]
+        print "FromSwtich:(GID=%lx, TYPE=%lx)\r\nVerify    :(GID=%lx, TYPE=%lx)"%(gs.group_id, gs.group_type, gv.group_id, gv.group_type)
+        if(len(gs.buckets) != len(gv.buckets)):
+            print "buckets len is not the same gs %lx, gv %lx",(len(gs.buckets), len(gv.buckets))
+
+        for j in range(len(gs.buckets)):
+           b1=gs.buckets[j]
+           b2=gv.buckets[j]
+           if(len(b1.actions) != len(b2.actions)):
+               print "action len is not the same"
+
+           for k in range(len(b1.actions)):
+               a1=b1.actions[k]
+               a2=b2.actions[k]
+               if(always_show == True):
+                   print "a1:"+a1.show()
+                   print "a2:"+a2.show()
+
+def AssertGroup(self, stats, verify_group_stats):
+    self.assertTrue(len(stats) ==len(verify_group_stats), "stats len is not the same")
+
+    for i in range(len(stats)):
+        gs = stats[i]
+        gv = verify_group_stats[i]
+        self.assertTrue(len(gs.buckets) == len(gv.buckets), "buckets len is not the same")
+
+        for j in range(len(gs.buckets)):
+           b1=gs.buckets[j]
+           b2=gv.buckets[j]
+           self.assertTrue(len(b1.actions) == len(b2.actions), "action len is not the same")
+
+           for k in range(len(b1.actions)):
+               a1=b1.actions[k]
+               a2=b2.actions[k]
+               self.assertEquals(a1, a2, "action is not the same")
+
+def encode_l2_interface_group_id(vlan, id):
+    return id + (vlan << OFDPA_VLAN_ID_SHIFT)
+
+def encode_l2_rewrite_group_id(id):
+    return id + (1 << OFDPA_GROUP_TYPE_SHIFT)
+
+def encode_l3_unicast_group_id(id):
+    return id + (2 << OFDPA_GROUP_TYPE_SHIFT)
+
+def encode_l2_mcast_group_id(vlan, id):
+    return id + (vlan << OFDPA_VLAN_ID_SHIFT) + (3 << OFDPA_GROUP_TYPE_SHIFT)
+
+def encode_l2_flood_group_id(vlan, id):
+    return id + (vlan << OFDPA_VLAN_ID_SHIFT) + (4 << OFDPA_GROUP_TYPE_SHIFT)
+
+def encode_l3_interface_group_id(id):
+    return id + (5 << OFDPA_GROUP_TYPE_SHIFT)
+
+def encode_l3_mcast_group_id(vlan, id):
+    return id + (vlan << OFDPA_VLAN_ID_SHIFT)+(6 << OFDPA_GROUP_TYPE_SHIFT)
+
+def encode_l3_ecmp_group_id(id):
+    return id + (7 << OFDPA_GROUP_TYPE_SHIFT)
+
+def encode_l2_unfiltered_group_id(id):
+    return id + (11 << OFDPA_GROUP_TYPE_SHIFT)
+
+def encode_l2_loadbal_group_id(id):
+    return id + (12 << OFDPA_GROUP_TYPE_SHIFT)
+
+def encode_l2_overlay_group_id(tunnel_id, subtype, index):
+    tunnel_id=tunnel_id&0xffff #16 bits
+    subtype = subtype&3        #2 bits
+    index = index & 0x3f       #10 bits
+    return index + (tunnel_id << OFDPA_TUNNEL_ID_SHIFT)+ (subtype<<OFDPA_TUNNEL_SUBTYPE_SHIFT)+(8 << OFDPA_GROUP_TYPE_SHIFT)
+
+def add_l2_unfiltered_group(ctrl, ports, send_barrier=False, allow_vlan_translation=1):
+    # group table
+    # set up untag groups for each port
+    group_id_list=[]
+    msgs=[]
+    for of_port in ports:
+        # do stuff
+        group_id = encode_l2_unfiltered_group_id(of_port)
+        group_id_list.append(group_id)
+        actions = [ofp.action.output(of_port)]
+
+        actions.append(ofp.action.set_field(ofp.oxm.exp1ByteValue(exp_type=24, value=allow_vlan_translation)))
+        buckets = [ofp.bucket(actions=actions)]
+        request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
+                                        group_id=group_id,
+                                        buckets=buckets
+                                       )
+        ctrl.message_send(request)
+        msgs.append(request)
+
+        if send_barrier:
+            do_barrier(ctrl)
+
+    return group_id_list, msgs
+
+def add_one_l2_unfiltered_group(ctrl, of_port, send_barrier=False):
+    # group table
+    # set up untag groups for each port
+    group_id = encode_l2_unfiltered_group_id(of_port)
+    actions = [ofp.action.output(of_port)]
+    actions.append(ofp.action.set_field(ofp.oxm.exp1ByteValue(exp_type=24, value=1)))
+
+    buckets = [ofp.bucket(actions=actions)]
+    request = ofp.message.group_add(
+        group_type=ofp.OFPGT_INDIRECT,
+        group_id=group_id,
+        buckets=buckets
+    )
+    ctrl.message_send(request)
+
+    if send_barrier:
+        do_barrier(ctrl)
+
+    return group_id, request
+
+def add_l2_interface_group(ctrl, ports, vlan_id=1, is_tagged=False, send_barrier=False):
+    # group table
+    # set up untag groups for each port
+    group_id_list=[]
+    msgs=[]
+    for of_port in ports:
+        # do stuff
+        group_id = encode_l2_interface_group_id(vlan_id, of_port)
+        group_id_list.append(group_id)
+        if is_tagged:
+            actions = [
+                ofp.action.output(of_port),
+            ]
+        else:
+            actions = [
+                ofp.action.pop_vlan(),
+                ofp.action.output(of_port),
+            ]
+
+        buckets = [
+            ofp.bucket(actions=actions),
+        ]
+
+        request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
+                                        group_id=group_id,
+                                        buckets=buckets
+                                       )
+        ctrl.message_send(request)
+        msgs.append(request)
+
+        if send_barrier:
+            do_barrier(ctrl)
+
+    return group_id_list, msgs
+
+def add_one_l2_interface_group(ctrl, port, vlan_id=1, is_tagged=False, send_barrier=False):
+    # group table
+    # set up untag groups for each port
+    group_id = encode_l2_interface_group_id(vlan_id, port)
+
+    if is_tagged:
+        actions = [
+            ofp.action.output(port),
+        ]
+    else:
+        actions = [
+            ofp.action.pop_vlan(),
+            ofp.action.output(port),
+        ]
+
+    buckets = [
+        ofp.bucket(actions=actions),
+    ]
+
+    request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
+                                    group_id=group_id,
+                                    buckets=buckets
+                                   )
+    ctrl.message_send(request)
+
+    if send_barrier:
+        do_barrier(ctrl)
+
+    return group_id, request
+
+def add_l2_mcast_group(ctrl, ports, vlanid, mcast_grp_index):
+    buckets=[]
+    for of_port in ports:
+        group_id = encode_l2_interface_group_id(vlanid, of_port)
+        action=[ofp.action.group(group_id)]
+        buckets.append(ofp.bucket(actions=action))
+
+    group_id =encode_l2_mcast_group_id(vlanid, mcast_grp_index)
+    request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
+                                    group_id=group_id,
+                                    buckets=buckets
+                                   )
+    ctrl.message_send(request)
+    return request
+
+def add_l2_flood_group(ctrl, ports, vlanid, id):
+    buckets=[]
+    for of_port in ports:
+        group_id = encode_l2_interface_group_id(vlanid, of_port)
+        action=[ofp.action.group(group_id)]
+        buckets.append(ofp.bucket(actions=action))
+
+    group_id =encode_l2_flood_group_id(vlanid, id)
+    request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
+                                    group_id=group_id,
+                                    buckets=buckets
+                                   )
+    ctrl.message_send(request)
+    return request
+
+def add_l2_flood_group_with_gids(ctrl, gids, vlanid, id, send_barrier=False):
+    buckets=[]
+    for gid in gids:
+        action=[ofp.action.group(gid)]
+        buckets.append(ofp.bucket(actions=action))
+
+    group_id =encode_l2_flood_group_id(vlanid, id)
+    request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
+                                    group_id=group_id,
+                                    buckets=buckets
+                                   )
+    ctrl.message_send(request)
+
+    if send_barrier:
+        do_barrier(ctrl)
+
+    return request
+
+def mod_l2_flood_group(ctrl, ports, vlanid, id):
+    buckets=[]
+    for of_port in ports:
+        group_id = encode_l2_interface_group_id(vlanid, of_port)
+        action=[ofp.action.group(group_id)]
+        buckets.append(ofp.bucket(actions=action))
+
+    group_id =encode_l2_flood_group_id(vlanid, id)
+    request = ofp.message.group_modify(group_type=ofp.OFPGT_ALL,
+                                    group_id=group_id,
+                                    buckets=buckets
+                                   )
+    ctrl.message_send(request)
+    return request
+
+
+def add_l2_rewrite_group(ctrl, port, vlanid, id, src_mac, dst_mac):
+    group_id = encode_l2_interface_group_id(vlanid, port)
+
+    action=[]
+    if src_mac is not None:
+        action.append(ofp.action.set_field(ofp.oxm.eth_src(src_mac)))
+
+    if dst_mac is not None:
+        action.append(ofp.action.set_field(ofp.oxm.eth_dst(dst_mac)))
+
+    action.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlanid)))
+
+    action.append(ofp.action.group(group_id))
+
+    buckets = [ofp.bucket(actions=action)]
+
+    group_id =encode_l2_rewrite_group_id(id)
+    request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
+                                    group_id=group_id,
+                                    buckets=buckets
+                                   )
+    ctrl.message_send(request)
+    return request
+
+def add_l3_unicast_group(ctrl, port, vlanid, id, src_mac, dst_mac, send_barrier=False, gid=None):
+
+    if (not gid):
+        group_id = encode_l2_interface_group_id(vlanid, port)
+    else:
+        group_id = gid
+
+    action=[]
+    if src_mac is not None:
+        action.append(ofp.action.set_field(ofp.oxm.eth_src(src_mac)))
+
+    if dst_mac is not None:
+        action.append(ofp.action.set_field(ofp.oxm.eth_dst(dst_mac)))
+
+    action.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlanid)))
+
+    action.append(ofp.action.group(group_id))
+
+    buckets = [ofp.bucket(actions=action)]
+
+    group_id =encode_l3_unicast_group_id(id)
+    request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
+                                    group_id=group_id,
+                                    buckets=buckets
+                                   )
+    ctrl.message_send(request)
+
+    if send_barrier:
+        do_barrier(ctrl)
+
+    return request
+
+def add_l3_interface_group(ctrl, port, vlanid, id, src_mac):
+    group_id = encode_l2_interface_group_id(vlanid, port)
+
+    action=[]
+    action.append(ofp.action.set_field(ofp.oxm.eth_src(src_mac)))
+    action.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlanid)))
+    action.append(ofp.action.group(group_id))
+
+    buckets = [ofp.bucket(actions=action)]
+
+    group_id =encode_l3_interface_group_id(id)
+    request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
+                                    group_id=group_id,
+                                    buckets=buckets
+                                   )
+    ctrl.message_send(request)
+    return request
+
+
+def add_l2_loadbal_group(ctrl, id, l2_unfil_intf_groups, send_barrier=False):
+    buckets=[]
+    for group in l2_unfil_intf_groups:
+        buckets.append(ofp.bucket(actions=[ofp.action.group(group)]))
+
+    group_id=encode_l2_loadbal_group_id(id)
+    request = ofp.message.group_add(group_type=ofp.OFPGT_SELECT,
+                                   group_id=group_id,
+                                   buckets=buckets
+                                   )
+    ctrl.message_send(request)
+    if send_barrier:
+        do_barrier(ctrl)
+
+    return group_id, request
+
+def mod_l2_loadbal_group(ctrl, id, l2_unfil_intf_groups, send_barrier=False):
+    buckets=[]
+    for group in l2_unfil_intf_groups:
+        buckets.append(ofp.bucket(actions=[ofp.action.group(group)]))
+
+    group_id =encode_l2_loadbal_group_id(id)
+    request = ofp.message.group_modify(group_type=ofp.OFPGT_SELECT,
+                                    group_id=group_id,
+                                    buckets=buckets
+                                   )
+    ctrl.message_send(request)
+    return request
+
+
+def add_l3_ecmp_group(ctrl, id, l3_ucast_groups, send_barrier=False):
+    buckets=[]
+    for group in l3_ucast_groups:
+        buckets.append(ofp.bucket(actions=[ofp.action.group(group)]))
+
+    group_id =encode_l3_ecmp_group_id(id)
+    request = ofp.message.group_add(group_type=ofp.OFPGT_SELECT,
+                                    group_id=group_id,
+                                    buckets=buckets
+                                   )
+    ctrl.message_send(request)
+
+    if send_barrier:
+        do_barrier(ctrl)
+
+    return request
+
+def mod_l3_ecmp_group(ctrl, id, l3_ucast_groups):
+    buckets=[]
+    for group in l3_ucast_groups:
+        buckets.append(ofp.bucket(actions=[ofp.action.group(group)]))
+
+    group_id =encode_l3_ecmp_group_id(id)
+    request = ofp.message.group_modify(group_type=ofp.OFPGT_SELECT,
+                                    group_id=group_id,
+                                    buckets=buckets
+                                    )
+    ctrl.message_send(request)
+    return request
+
+def add_l3_mcast_group(ctrl, vid,  mcast_group_id, groups_on_buckets):
+    buckets=[]
+    for group in groups_on_buckets:
+        buckets.append(ofp.bucket(actions=[ofp.action.group(group)]))
+
+    group_id =encode_l3_mcast_group_id(vid, mcast_group_id)
+    request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
+                                    group_id=group_id,
+                                    buckets=buckets
+                                   )
+    ctrl.message_send(request)
+    return request
+
+def add_l2_overlay_flood_over_unicast_tunnel_group(ctrl, tunnel_id, ports, index):
+    buckets=[]
+    for port in ports:
+        buckets.append(ofp.bucket(actions=[ofp.action.output(port)]))
+
+    group_id=encode_l2_overlay_group_id(tunnel_id, 0, index)
+    request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
+                                    group_id=group_id,
+                                    buckets=buckets
+                                   )
+    ctrl.message_send(request)
+    return request
+
+def add_l2_overlay_flood_over_mcast_tunnel_group(ctrl, tunnel_id, ports, index):
+    buckets=[]
+    for port in ports:
+        buckets.append(ofp.bucket(actions=[ofp.action.output(port)]))
+
+    group_id=encode_l2_overlay_group_id(tunnel_id, 1, index)
+    request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
+                                    group_id=group_id,
+                                    buckets=buckets
+                                   )
+    ctrl.message_send(request)
+    return request
+
+def add_l2_overlay_mcast_over_unicast_tunnel_group(ctrl, tunnel_id, ports, index):
+    buckets=[]
+    for port in ports:
+        buckets.append(ofp.bucket(actions=[ofp.action.output(port)]))
+
+    group_id=encode_l2_overlay_group_id(tunnel_id, 2, index)
+    request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
+                                    group_id=group_id,
+                                    buckets=buckets
+                                   )
+    ctrl.message_send(request)
+    return request
+
+def add_l2_overlay_mcast_over_mcast_tunnel_group(ctrl, tunnel_id, ports, index):
+    buckets=[]
+    for port in ports:
+        buckets.append(ofp.bucket(actions=[ofp.action.output(port)]))
+
+    group_id=encode_l2_overlay_group_id(tunnel_id, 3, index)
+    request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
+                                    group_id=group_id,
+                                    buckets=buckets
+                                   )
+    ctrl.message_send(request)
+    return request
+
+def add_port_table_flow(ctrl, is_overlay=True):
+    match = ofp.match()
+
+    if is_overlay == True:
+       match.oxm_list.append(ofp.oxm.in_port(0x10000))
+       NEXT_TABLE=50
+    else:
+       match.oxm_list.append(ofp.oxm.in_port(0))
+       NEXT_TABLE=10
+
+    request = ofp.message.flow_add(
+        table_id=0,
+        cookie=42,
+        match=match,
+        instructions=[
+          ofp.instruction.goto_table(NEXT_TABLE)
+        ],
+        priority=0)
+    logging.info("Add port table, match port %lx" % 0x10000)
+    ctrl.message_send(request)
+
+def pop_vlan_flow(ctrl, ports, vlan_id=1):
+    # table 10: vlan
+    # goto to table 20
+    msgs=[]
+    for of_port in ports:
+            match = ofp.match()
+            match.oxm_list.append(ofp.oxm.in_port(of_port))
+            match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlan_id))
+            request = ofp.message.flow_add(
+                table_id=10,
+                cookie=42,
+                match=match,
+                instructions=[
+                  ofp.instruction.apply_actions(
+                    actions=[
+                      ofp.action.pop_vlan()
+                    ]
+                  ),
+                  ofp.instruction.goto_table(20)
+                ],
+                priority=0)
+            logging.info("Add vlan %d tagged packets on port %d and go to table 20" %( vlan_id, of_port))
+            ctrl.message_send(request)
+
+
+    return msgs
+
+def add_vlan_table_flow(ctrl, ports, vlan_id=1, flag=VLAN_TABLE_FLAG_ONLY_BOTH, send_barrier=False):
+    # table 10: vlan
+    # goto to table 20
+    msgs=[]
+    for of_port in ports:
+        if (flag == VLAN_TABLE_FLAG_ONLY_TAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH) or (flag == 4):
+            match = ofp.match()
+            match.oxm_list.append(ofp.oxm.in_port(of_port))
+            match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlan_id))
+            request = ofp.message.flow_add(
+                table_id=10,
+                cookie=42,
+                match=match,
+                instructions=[
+                  ofp.instruction.apply_actions(
+                    actions=[
+                      ofp.action.pop_vlan()
+                    ]
+                  ),
+                  ofp.instruction.goto_table(20)
+                ],
+                priority=0)
+            logging.info("Add vlan %d tagged packets on port %d and go to table 20" %( vlan_id, of_port))
+            ctrl.message_send(request)
+
+        if (flag == VLAN_TABLE_FLAG_ONLY_UNTAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH):
+            match = ofp.match()
+            match.oxm_list.append(ofp.oxm.in_port(of_port))
+            match.oxm_list.append(ofp.oxm.vlan_vid_masked(0, 0x1fff))
+            request = ofp.message.flow_add(
+                table_id=10,
+                cookie=42,
+                match=match,
+                instructions=[
+                  ofp.instruction.apply_actions(
+                    actions=[
+                      ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlan_id))
+                    ]
+                  ),
+                  ofp.instruction.goto_table(20)
+                ],
+                priority=0)
+            logging.info("Add vlan %d untagged packets on port %d and go to table 20" % (vlan_id, of_port))
+            ctrl.message_send(request)
+            msgs.append(request)
+
+        if (flag == 4) :
+            match = ofp.match()
+            match.oxm_list.append(ofp.oxm.in_port(of_port))
+            match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000, 0x1fff))
+            request = ofp.message.flow_add(
+                table_id=10,
+                cookie=42,
+                match=match,
+                instructions=[
+                  ofp.instruction.apply_actions(
+                    actions=[
+                      ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlan_id))
+                    ]
+                  ),
+                  ofp.instruction.goto_table(20)
+                ],
+                priority=0)
+            logging.info("Add vlan %d untagged packets on port %d and go to table 20" % (vlan_id, of_port))
+            ctrl.message_send(request)
+            msgs.append(request)
+
+    if send_barrier:
+        do_barrier(ctrl)
+
+    return msgs
+
+def del_vlan_table_flow(ctrl, ports, vlan_id=1, flag=VLAN_TABLE_FLAG_ONLY_BOTH, send_barrier=False):
+    # table 10: vlan
+    # goto to table 20
+    msgs=[]
+    for of_port in ports:
+        if (flag == VLAN_TABLE_FLAG_ONLY_TAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH):
+            match = ofp.match()
+            match.oxm_list.append(ofp.oxm.in_port(of_port))
+            match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlan_id))
+            request = ofp.message.flow_delete(
+                table_id=10,
+                cookie=42,
+                match=match,
+                priority=0)
+            logging.info("Del vlan %d tagged packets on port %d and go to table 20" %( vlan_id, of_port))
+            ctrl.message_send(request)
+
+        if (flag == VLAN_TABLE_FLAG_ONLY_UNTAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH):
+            match = ofp.match()
+            match.oxm_list.append(ofp.oxm.in_port(of_port))
+            match.oxm_list.append(ofp.oxm.vlan_vid_masked(0, 0xfff))
+            request = ofp.message.flow_delete(
+                table_id=10,
+                cookie=42,
+                match=match,
+                priority=0)
+            logging.info("Del vlan %d untagged packets on port %d and go to table 20" % (vlan_id, of_port))
+            ctrl.message_send(request)
+            msgs.append(request)
+
+    if send_barrier:
+        do_barrier(ctrl)
+
+    return msgs
+
+def add_vlan_table_flow_pvid(ctrl, in_port, match_vid=None, pvid=1, send_barrier=False):
+    """it will tag pack as untagged packet wether it has tagg or not"""
+    match = ofp.match()
+    match.oxm_list.append(ofp.oxm.in_port(in_port))
+    actions=[]
+    if match_vid == None:
+        match.oxm_list.append(ofp.oxm.vlan_vid(0))
+        actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+pvid)))
+        goto_table=20
+    else:
+        match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+match_vid, 0x1fff))
+        actions.append(ofp.action.push_vlan(0x8100))
+        actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+pvid)))
+        goto_table=20
+
+    request = ofp.message.flow_add(
+        table_id=10,
+        cookie=42,
+        match=match,
+        instructions=[
+             ofp.instruction.apply_actions(actions=actions)
+            ,ofp.instruction.goto_table(goto_table)
+        ],
+        priority=0)
+    logging.info("Add PVID %d on port %d and go to table %ld" %( pvid, in_port, goto_table))
+    ctrl.message_send(request)
+
+    if send_barrier:
+        do_barrier(ctrl)
+
+def add_vlan_table_flow_allow_all_vlan(ctrl, in_port, send_barrier=False):
+    """it st flow allow all vlan tag on this port"""
+    match = ofp.match()
+    match.oxm_list.append(ofp.oxm.in_port(in_port))
+    match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000, 0x1000))
+    request = ofp.message.flow_add(
+        table_id=10,
+        cookie=42,
+        match=match,
+        instructions=[
+            ofp.instruction.goto_table(20)
+        ],
+        priority=0)
+    logging.info("Add allow all vlan on port %d " %(in_port))
+    ctrl.message_send(request)
+
+def add_one_vlan_table_flow_translation(ctrl, of_port, vlan_id=1, new_vlan_id=-1, vrf=0, flag=VLAN_TABLE_FLAG_ONLY_BOTH, send_barrier=False):
+    # Install a flow for VLAN translation
+    # in VLAN table.
+    # table 10: vlan
+    # goto to table 20
+    if (flag == VLAN_TABLE_FLAG_ONLY_TAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH) or (flag == 4):
+        match = ofp.match()
+        match.oxm_list.append(ofp.oxm.in_port(of_port))
+        match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+vlan_id,0x1fff))
+
+        actions=[]
+        if vrf!=0:
+            actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=1, value=vrf)))
+        if new_vlan_id != -1:
+            actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+new_vlan_id)))
+
+        request = ofp.message.flow_add(
+            table_id=10,
+            cookie=42,
+            match=match,
+            instructions=[
+                ofp.instruction.apply_actions(
+                     actions=actions
+                ),
+                ofp.instruction.goto_table(20)
+            ],
+            priority=0)
+        logging.info("Add vlan %d tagged packets on port %d and go to table 20" %( vlan_id, of_port))
+        ctrl.message_send(request)
+
+
+def add_one_egress_vlan_table_flow(ctrl, of_port, match_vlan, inner_vlan, outer_vlan):
+
+    # used for translating single to double tagged packets only
+
+    match = ofp.match()
+    match.oxm_list.append(ofp.oxm.exp4ByteValue(ofp.oxm.OFDPA_EXP_TYPE_ACTSET_OUTPUT, of_port))
+    match.oxm_list.append(ofp.oxm.exp1ByteValue(ofp.oxm.OFDPA_EXP_TYPE_ALLOW_VLAN_TRANSLATION, 1))
+    match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+match_vlan,0x1fff))
+
+    actions=[]
+    actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+inner_vlan)))
+    actions.append(ofp.action.push_vlan(0x8100))
+    actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+outer_vlan)))
+
+    request = ofp.message.flow_add(
+            table_id=EGRESS_VLAN_FLOW_TABLE,
+            cookie=42,
+            match=match,
+            instructions=[
+                ofp.instruction.apply_actions(
+                     actions=actions
+                ),
+                ofp.instruction.goto_table(EGRESS_DSCP_TABLE)
+            ],
+            priority=0)
+
+    ctrl.message_send(request)
+
+    return
+
+def add_one_vlan_table_flow(ctrl, of_port, out_vlan_id=1, vlan_id=1, vrf=0, flag=VLAN_TABLE_FLAG_ONLY_BOTH, send_barrier=False):
+
+    # goto to table 20
+    if (flag == VLAN_TABLE_FLAG_ONLY_TAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH) or (flag == 4):
+        match = ofp.match()
+        match.oxm_list.append(ofp.oxm.in_port(of_port))
+        match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+vlan_id,0x1fff))
+
+        actions=[]
+        if config["switch_type"] != 'xpliant' and vrf != 0:
+            actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=1, value=vrf)))
+
+        #actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(value=vlan_id)))
+
+        request = ofp.message.flow_add(
+            table_id=10,
+            cookie=42,
+            match=match,
+            instructions=[
+                ofp.instruction.apply_actions(
+                     actions=actions
+                ),
+                ofp.instruction.goto_table(20)
+            ],
+            priority=0)
+        logging.info("Add vlan %d tagged packets on port %d and go to table 20" %( vlan_id, of_port))
+        ctrl.message_send(request)
+
+    if (flag == VLAN_TABLE_FLAG_ONLY_UNTAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH):
+
+        match = ofp.match()
+        match.oxm_list.append(ofp.oxm.in_port(of_port))
+        match.oxm_list.append(ofp.oxm.vlan_vid_masked(0, 0x1fff))
+
+        actions=[]
+        if vrf!=0:
+            actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=1, value=vrf)))
+
+        # actions.append(ofp.action.push_vlan(0x8100))
+        actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlan_id)))
+
+        request = ofp.message.flow_add(
+            table_id=10,
+            cookie=42,
+            match=match,
+            instructions=[
+              ofp.instruction.apply_actions(
+                actions=actions
+              ),
+              ofp.instruction.goto_table(20)
+            ],
+            priority=0)
+        logging.info("Add vlan %d untagged packets on port %d and go to table 20" % (vlan_id, of_port))
+        ctrl.message_send(request)
+
+    if (flag == 4) :
+        match = ofp.match()
+        match.oxm_list.append(ofp.oxm.in_port(of_port))
+        match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000,0x1fff))
+
+        actions=[]
+        if vrf!=0:
+            actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=1, value=vrf)))
+
+        actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlan_id)))
+
+        request = ofp.message.flow_add(
+            table_id=10,
+            cookie=42,
+            match=match,
+            instructions=[
+                ofp.instruction.apply_actions(
+                     actions=actions
+                ),
+                ofp.instruction.goto_table(20)
+            ],
+            priority=0)
+        logging.info("Add vlan %d tagged packets on port %d and go to table 20" %( vlan_id, of_port))
+        ctrl.message_send(request)
+
+    if (flag == VLAN_TABLE_FLAG_ONLY_STACKED):
+        # This flag is meant to managed stacked vlan packtes
+        # Matches on outer VLAN_ID, set OVID with outer VLAN.
+        # Finally expose inner VLAN_ID with a pop action and
+        # goto VLAN_1_FLOW_TABLE
+        match = ofp.match()
+        match.oxm_list.append(ofp.oxm.in_port(of_port))
+        match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+vlan_id,0x1fff))
+
+        actions=[]
+        # actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_OVID, value=0x1000+vlan_id)))
+        actions.append(ofp.action.pop_vlan())
+        actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_OVID, value=0x1000+vlan_id)))
+
+        request = ofp.message.flow_add(
+            table_id=10,
+            cookie=42,
+            match=match,
+            instructions=[
+                ofp.instruction.apply_actions(
+                     actions=actions
+                ),
+                ofp.instruction.goto_table(VLAN_1_FLOW_TABLE)
+            ],
+            priority=0)
+        logging.info("Add vlan %d tagged packets on port %d and go to table %d" %( vlan_id, of_port, VLAN_1_FLOW_TABLE))
+        ctrl.message_send(request)
+
+    if (flag == VLAN_TABLE_FLAG_PRIORITY) :
+            match = ofp.match()
+            match.oxm_list.append(ofp.oxm.in_port(of_port))
+            match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000, 0x1fff))
+            request = ofp.message.flow_add(
+                table_id=10,
+                cookie=42,
+                match=match,
+                instructions=[
+                  ofp.instruction.apply_actions(
+                    actions=[
+                        ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlan_id)),
+                        ofp.action.push_vlan(0x8100),
+                        ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+out_vlan_id)),
+                    ]
+                  ),
+                  ofp.instruction.goto_table(20)
+                ],
+                priority=0)
+            logging.info("Add vlan %d untagged packets on port %d and go to table 20" % (vlan_id, of_port))
+            ctrl.message_send(request)
+
+    if send_barrier:
+        do_barrier(ctrl)
+
+    return request
+
+def add_one_vlan_table_flow_pw(ctrl, of_port, tunnel_index, new_vlan_id=1, vlan_id=1, vrf=0, flag=VLAN_TABLE_FLAG_ONLY_TAG, send_barrier=False):
+    # table 10: vlan
+    # goto to table 13
+    if flag == VLAN_TABLE_FLAG_ONLY_TAG:
+        match = ofp.match()
+        match.oxm_list.append(ofp.oxm.in_port(of_port))
+        match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+vlan_id, 0x1fff))
+
+        actions=[]
+        if vlan_id == -1:
+            actions.append(ofp.action.pop_vlan())
+        if new_vlan_id > 1:
+            actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+new_vlan_id)))
+        actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_MPLS_TYPE, value=ofp.oxm.VPWS)))
+        actions.append(ofp.action.set_field(ofp.oxm.tunnel_id(tunnel_index + ofp.oxm.TUNNEL_ID_BASE)))
+        # 0x0000nnnn is for UNI interfaces
+        actions.append(ofp.action.set_field(ofp.oxm.exp4ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_MPLS_L2_PORT, value=0x00000000 + of_port)))
+
+        request = ofp.message.flow_add(
+            table_id=10,
+            cookie=42,
+            match=match,
+            instructions=[
+              ofp.instruction.apply_actions(
+                actions=actions
+              ),
+              ofp.instruction.goto_table(MPLS_L2_PORT_FLOW_TABLE)
+            ],
+            priority=0)
+        logging.info("Add vlan %d tagged packets on port %d and go to table %d" % (vlan_id, of_port, MPLS_L2_PORT_FLOW_TABLE))
+        ctrl.message_send(request)
+
+    if flag == VLAN_TABLE_FLAG_ONLY_UNTAG:
+        match = ofp.match()
+        match.oxm_list.append(ofp.oxm.in_port(of_port))
+        match.oxm_list.append(ofp.oxm.vlan_vid(0))
+
+        actions=[]
+        if vlan_id > 1:
+    #        actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlan_id)))
+    #        actions.append(ofp.action.set_field(ofp.action.push_vlan(0x8100)))
+            actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlan_id)))
+
+        actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_MPLS_TYPE, value=ofp.oxm.VPWS)))
+        actions.append(ofp.action.set_field(ofp.oxm.tunnel_id(tunnel_index + ofp.oxm.TUNNEL_ID_BASE)))
+        # 0x0000nnnn is for UNI interfaces
+        actions.append(ofp.action.set_field(ofp.oxm.exp4ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_MPLS_L2_PORT, value=0x00000000 + of_port)))
+
+        request = ofp.message.flow_add(
+            table_id=10,
+            cookie=42,
+            match=match,
+            instructions=[
+              ofp.instruction.apply_actions(
+                actions=actions
+              ),
+              ofp.instruction.goto_table(MPLS_L2_PORT_FLOW_TABLE)
+            ],
+            priority=0)
+        logging.info("Add vlan %d untagged packets on port %d and go to table %d" % (vlan_id, of_port, MPLS_L2_PORT_FLOW_TABLE))
+        ctrl.message_send(request)
+
+    if send_barrier:
+        do_barrier(ctrl)
+
+    return request
+
+def add_one_vlan_1_table_flow(ctrl, of_port, new_outer_vlan_id=-1, outer_vlan_id=1, inner_vlan_id=1, flag=VLAN_TABLE_FLAG_ONLY_TAG, send_barrier=False):
+
+    # table 11: vlan 1 table
+    # goto to table 20
+    if flag == VLAN_TABLE_FLAG_ONLY_TAG:
+        match = ofp.match()
+        match.oxm_list.append(ofp.oxm.in_port(of_port))
+        match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+inner_vlan_id,0x1fff))
+        match.oxm_list.append(ofp.oxm.exp2ByteValue(ofp.oxm.OFDPA_EXP_TYPE_OVID, 0x1000+outer_vlan_id))
+
+        actions=[]
+        actions.append(ofp.action.push_vlan(0x8100))
+        if new_outer_vlan_id != -1:
+            actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+new_outer_vlan_id)))
+        else:
+            actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+outer_vlan_id)))
+
+        request = ofp.message.flow_add(
+            table_id=11,
+            cookie=42,
+            match=match,
+            instructions=[
+                ofp.instruction.apply_actions(
+                     actions=actions
+                ),
+                ofp.instruction.goto_table(TERMINATION_FLOW_TABLE)
+            ],
+            priority=0)
+        logging.info("Add vlan 1 double tagged %d-%d packets on port %d and go to table %d" %( outer_vlan_id, inner_vlan_id, of_port, TERMINATION_FLOW_TABLE))
+        ctrl.message_send(request)
+
+    if flag == VLAN_TABLE_FLAG_ONLY_UNTAG:
+
+        match = ofp.match()
+        match.oxm_list.append(ofp.oxm.in_port(of_port))
+        match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+inner_vlan_id,0x1fff))
+        match.oxm_list.append(ofp.oxm.exp2ByteValue(ofp.oxm.OFDPA_EXP_TYPE_OVID, 0x1000+outer_vlan_id))
+
+        actions=[]
+        request = ofp.message.flow_add(
+            table_id=11,
+            cookie=42,
+            match=match,
+            instructions=[
+                ofp.instruction.apply_actions(
+                     actions=actions
+                ),
+                ofp.instruction.goto_table(TERMINATION_FLOW_TABLE)
+            ],
+            priority=0)
+        logging.info("Add vlan 1 double tagged %d-%d packets on port %d and go to table %d" %( outer_vlan_id, inner_vlan_id, of_port, TERMINATION_FLOW_TABLE))
+        ctrl.message_send(request)
+
+    if flag == VLAN_TABLE_FLAG_ONLY_POP_VLAN:
+
+        print("INSTALLIN IN TABLE 11!")
+
+        match = ofp.match()
+        match.oxm_list.append(ofp.oxm.in_port(of_port))
+        match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+inner_vlan_id,0x1fff))
+        match.oxm_list.append(ofp.oxm.exp2ByteValue(ofp.oxm.OFDPA_EXP_TYPE_OVID, 0x1000+outer_vlan_id))
+
+        actions=[]
+        actions.append(ofp.action.pop_vlan())
+
+        request = ofp.message.flow_add(
+            table_id=11,
+            cookie=42,
+            match=match,
+            instructions=[
+                ofp.instruction.apply_actions(
+                     actions=actions
+                ),
+                ofp.instruction.goto_table(TERMINATION_FLOW_TABLE)
+            ],
+            priority=0)
+        logging.info("Add vlan 1 double tagged %d-%d packets on port %d and go to table %d" %( outer_vlan_id, inner_vlan_id, of_port, TERMINATION_FLOW_TABLE))
+        ctrl.message_send(request)
+
+
+    if send_barrier:
+        do_barrier(ctrl)
+
+    return request
+
+def add_one_vlan_1_table_flow_pw(ctrl, of_port, tunnel_index, new_outer_vlan_id=-1, outer_vlan_id=1, inner_vlan_id=1, flag=VLAN_TABLE_FLAG_ONLY_TAG, cross_connect=False, send_barrier=False):
+
+    # table 11: vlan 1 table
+    # goto to table 13
+    match = ofp.match()
+    match.oxm_list.append(ofp.oxm.in_port(of_port))
+    match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+inner_vlan_id,0x1fff))
+    match.oxm_list.append(ofp.oxm.exp2ByteValue(ofp.oxm.OFDPA_EXP_TYPE_OVID, 0x1000+outer_vlan_id))
+
+    actions=[]
+
+    if cross_connect:
+        actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+inner_vlan_id)))
+    actions.append(ofp.action.push_vlan(0x8100))
+    if new_outer_vlan_id != -1:
+        actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+new_outer_vlan_id)))
+    else:
+        actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+outer_vlan_id)))
+
+    if not cross_connect:
+        actions.append(ofp.action.set_field(ofp.oxm.tunnel_id(tunnel_index + ofp.oxm.TUNNEL_ID_BASE)))
+        actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_MPLS_TYPE, value=ofp.oxm.VPWS)))
+    else:
+        actions.append(ofp.action.set_field(ofp.oxm.tunnel_id(tunnel_index + ofp.oxm.TUNNEL_ID_BASE_CROSS_CONNECT)))
+
+    # 0x0000nnnn is for UNI interfaces
+    actions.append(ofp.action.set_field(ofp.oxm.exp4ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_MPLS_L2_PORT, value=0x00000000 + of_port)))
+
+    request = ofp.message.flow_add(
+        table_id=11,
+        cookie=42,
+        match=match,
+        instructions=[
+            ofp.instruction.apply_actions(
+                 actions=actions
+            ),
+            ofp.instruction.goto_table(MPLS_L2_PORT_FLOW_TABLE)
+        ],
+        priority=0)
+    logging.info("Add vlan 1 double tagged %d-%d packets on port %d and go to table %d" %( outer_vlan_id, inner_vlan_id, of_port, MPLS_L2_PORT_FLOW_TABLE))
+    ctrl.message_send(request)
+    if send_barrier:
+        do_barrier(ctrl)
+
+    return request
+
+def add_bridge_flow(ctrl, dst_mac, vlanid, group_id, send_barrier=False):
+    match = ofp.match()
+    priority=500
+    if dst_mac!=None:
+        priority=1000
+        match.oxm_list.append(ofp.oxm.eth_dst(dst_mac))
+
+    match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlanid))
+
+    request = ofp.message.flow_add(
+            table_id=50,
+            cookie=42,
+            match=match,
+            instructions=[
+                ofp.instruction.write_actions(
+                    actions=[
+                        ofp.action.group(group_id)]),
+                    ofp.instruction.goto_table(60)
+                ],
+            buffer_id=ofp.OFP_NO_BUFFER,
+            priority=priority)
+
+    logging.info("Inserting Brdige flow vlan %d, mac %s", vlanid, dst_mac)
+    ctrl.message_send(request)
+
+    if send_barrier:
+        do_barrier(ctrl)
+
+    return request
+
+def add_overlay_bridge_flow(ctrl, dst_mac, vnid, group_id, is_group=True, send_barrier=False):
+    match = ofp.match()
+    if dst_mac!=None:
+        match.oxm_list.append(ofp.oxm.eth_dst(dst_mac))
+
+    match.oxm_list.append(ofp.oxm.tunnel_id(vnid))
+    if is_group == True:
+        actions=[ofp.action.group(group_id)]
+    else:
+        actions=[ofp.action.output(group_id)]
+
+    request = ofp.message.flow_add(
+            table_id=50,
+            cookie=42,
+            match=match,
+            instructions=[
+                ofp.instruction.write_actions(
+                    actions=actions),
+                    ofp.instruction.goto_table(60)
+                ],
+            buffer_id=ofp.OFP_NO_BUFFER,
+            priority=1000)
+
+    logging.info("Inserting Brdige flow vnid %d, mac %s", vnid, dst_mac)
+    ctrl.message_send(request)
+
+    if send_barrier:
+        do_barrier(ctrl)
+
+    return request
+
+def add_termination_flow(ctrl, in_port, eth_type, dst_mac, vlanid, goto_table=None, send_barrier=False):
+    match = ofp.match()
+    match.oxm_list.append(ofp.oxm.eth_type(eth_type))
+    if dst_mac[0]&0x01 == 0x01:
+       match.oxm_list.append(ofp.oxm.eth_dst_masked(dst_mac, [0xff, 0xff, 0xff, 0x80, 0x00, 0x00]))
+       goto_table=40
+    else:
+       if in_port!=0:
+           match.oxm_list.append(ofp.oxm.in_port(in_port))
+       match.oxm_list.append(ofp.oxm.eth_dst(dst_mac))
+       match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlanid))
+       if goto_table == None:
+           goto_table=30
+
+    request = ofp.message.flow_add(
+            table_id=20,
+            cookie=42,
+            match=match,
+            instructions=[
+                    ofp.instruction.goto_table(goto_table)
+                ],
+            buffer_id=ofp.OFP_NO_BUFFER,
+            priority=1)
+
+    logging.info("Inserting termination flow inport %d, eth_type %lx, vlan %d, mac %s", in_port, eth_type, vlanid, dst_mac)
+    ctrl.message_send(request)
+    if send_barrier:
+        do_barrier(ctrl)
+
+    return request
+
+def add_unicast_routing_flow(ctrl, eth_type, dst_ip, mask, action_group_id, vrf=0, send_ctrl=False, send_barrier=False, priority = 1):
+    match = ofp.match()
+    match.oxm_list.append(ofp.oxm.eth_type(eth_type))
+    if config["switch_type"] != 'xpliant' and vrf != 0:
+        match.oxm_list.append(ofp.oxm.exp2ByteValue(ofp.oxm.OFDPA_EXP_TYPE_VRF, vrf))
+
+    match.oxm_list.append(ofp.oxm.ipv4_dst_masked(dst_ip, mask))
+
+    instructions = []
+    instructions.append(ofp.instruction.goto_table(60))
+    if send_ctrl:
+        instructions.append(ofp.instruction.write_actions(
+                            actions=[ofp.action.output( port=ofp.OFPP_CONTROLLER,
+                            max_len=ofp.OFPCML_NO_BUFFER)]))
+    else:
+        instructions.append(ofp.instruction.write_actions(
+                        actions=[ofp.action.group(action_group_id)]))
+
+    request = ofp.message.flow_add(
+            table_id=30,
+            cookie=42,
+            match=match,
+            instructions=instructions,
+            buffer_id=ofp.OFP_NO_BUFFER,
+            priority=priority)
+
+    logging.info("Inserting unicast routing flow eth_type %lx, dip %ld",eth_type, dst_ip)
+    ctrl.message_send(request)
+
+    if send_barrier:
+        do_barrier(ctrl)
+
+    return request
+
+def add_unicast_blackhole_flow(ctrl, eth_type, dst_ip, mask, vrf=0, send_ctrl=False, send_barrier=False, priority = 1):
+    match = ofp.match()
+    match.oxm_list.append(ofp.oxm.eth_type(eth_type))
+    if config["switch_type"] != 'xpliant' and vrf != 0:
+        match.oxm_list.append(ofp.oxm.exp2ByteValue(ofp.oxm.OFDPA_EXP_TYPE_VRF, vrf))
+
+    match.oxm_list.append(ofp.oxm.ipv4_dst_masked(dst_ip, mask))
+
+    instructions = []
+    instructions.append(ofp.instruction.goto_table(60))
+    instructions.append(ofp.instruction.clear_actions( ))
+
+    request = ofp.message.flow_add(
+            table_id=30,
+            cookie=42,
+            match=match,
+            instructions=instructions,
+            buffer_id=ofp.OFP_NO_BUFFER,
+            priority=priority)
+
+    logging.info("Inserting unicast blackhole routing flow eth_type %lx, dip %ld",eth_type, dst_ip)
+    ctrl.message_send(request)
+
+    if send_barrier:
+        do_barrier(ctrl)
+
+    return request
+
+def add_unicast_v6_routing_flow(ctrl, eth_type, dst_ip, mask, action_group_id, vrf=0, send_ctrl=False, send_barrier=False):
+    match = ofp.match()
+    match.oxm_list.append(ofp.oxm.eth_type(eth_type))
+    if vrf != 0:
+        match.oxm_list.append(ofp.oxm.exp2ByteValue(ofp.oxm.OFDPA_EXP_TYPE_VRF, vrf))
+
+    match.oxm_list.append(ofp.oxm.ipv6_dst_masked(parse_ipv6(dst_ip), parse_ipv6(mask)))
+
+    instructions = []
+    instructions.append(ofp.instruction.goto_table(60))
+    if send_ctrl:
+        instructions.append(ofp.instruction.write_actions(
+                            actions=[ofp.action.output( port=ofp.OFPP_CONTROLLER,
+                            max_len=ofp.OFPCML_NO_BUFFER)]))
+    else:
+        instructions.append(ofp.instruction.write_actions(
+                        actions=[ofp.action.group(action_group_id)]))
+
+    request = ofp.message.flow_add(
+            table_id=30,
+            cookie=42,
+            match=match,
+            instructions=instructions,
+            buffer_id=ofp.OFP_NO_BUFFER,
+            priority=1)
+
+    logging.info("Inserting unicast routing flow eth_type %lx, dip %s",eth_type, dst_ip)
+    ctrl.message_send(request)
+
+    if send_barrier:
+        do_barrier(ctrl)
+
+    return request
+
+def add_mpls_flow(ctrl, action_group_id=0x0, label=100 ,ethertype=0x0800, bos=1, vrf=1, goto_table=27, dec_ttl=False, send_barrier=False):
+    match = ofp.match()
+    match.oxm_list.append(ofp.oxm.eth_type(0x8847))
+    match.oxm_list.append(ofp.oxm.mpls_label(label))
+    match.oxm_list.append(ofp.oxm.mpls_bos(bos))
+    write_actions = []
+    write_actions.append(ofp.action.group(action_group_id))
+    apply_actions = []
+    apply_actions = [ofp.action.dec_mpls_ttl(),
+               ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=1, value=vrf))]
+    if (goto_table != 29):
+            apply_actions.append(ofp.action.set_field(
+                            ofp.oxm.exp2ByteValue(exp_type=23, value=32)))
+            apply_actions.append(ofp.action.copy_ttl_in())
+
+    request = ofp.message.flow_add(
+            table_id=24,
+            cookie=43,
+            match=match,
+            instructions=[
+                    ofp.instruction.apply_actions(actions=apply_actions),
+                    ofp.instruction.write_actions(actions=write_actions),
+                    ofp.instruction.goto_table(goto_table)
+                ],
+            buffer_id=ofp.OFP_NO_BUFFER,
+            priority=1)
+    ctrl.message_send(request)
+
+    if send_barrier:
+        do_barrier(ctrl)
+
+    return request
+
+def xpliant_add_mpls_flow(ctrl, action_group_id=0x0, label=100 ,ethertype=0x0800, bos=1, vrf=1, goto_table=27, send_barrier=False):
+    match = ofp.match()
+    match.oxm_list.append(ofp.oxm.eth_type(0x8847))
+    match.oxm_list.append(ofp.oxm.mpls_label(label))
+
+    apply_actions = []
+    apply_actions.append(ofp.action.group(action_group_id))
+    apply_actions.append(ofp.action.dec_mpls_ttl())
+    if (goto_table != 29):
+        apply_actions.append(ofp.action.pop_mpls(ethertype))
+
+    request = ofp.message.flow_add(
+            table_id=24,
+            cookie=43,
+            match=match,
+            instructions=[
+                    ofp.instruction.apply_actions(actions=apply_actions),
+                ],
+            buffer_id=ofp.OFP_NO_BUFFER,
+            priority=1)
+    logging.info("Inserting MPLS flow , label %ld", label)
+    ctrl.message_send(request)
+
+    if send_barrier:
+        do_barrier(ctrl)
+
+    return request
+
+def add_mpls_flow_swap(ctrl, action_group_id, label, ethertype, bos, goto_table=MPLS_TYPE_FLOW_TABLE, of_port=0, send_barrier=False):
+    match = ofp.match()
+    match.oxm_list.append(ofp.oxm.eth_type(0x8847))
+    match.oxm_list.append(ofp.oxm.mpls_label(label))
+    match.oxm_list.append(ofp.oxm.mpls_bos(1))
+
+    apply_actions = []
+    write_actions = []
+    apply_actions.append(ofp.action.dec_mpls_ttl())
+    write_actions.append(ofp.action.group(action_group_id))
+
+    request = ofp.message.flow_add(
+            table_id=24,
+            cookie=43,
+            match=match,
+            instructions=[
+                    ofp.instruction.apply_actions(actions=apply_actions),
+                    ofp.instruction.write_actions(actions=write_actions),
+                    ofp.instruction.goto_table(goto_table)
+                ],
+            buffer_id=ofp.OFP_NO_BUFFER,
+            priority=1)
+
+    logging.info("Inserting MPLS flow , label %ld", label)
+    ctrl.message_send(request)
+
+    if send_barrier:
+        do_barrier(ctrl)
+
+    return request
+
+
+def add_mpls_flow_pw(ctrl, action_group_id, label, ethertype, bos, tunnel_index, goto_table=MPLS_TYPE_FLOW_TABLE, popMPLS=True, popL2=False, of_port=0, send_barrier=False):
+    match = ofp.match()
+    match.oxm_list.append(ofp.oxm.eth_type(0x8847))
+    match.oxm_list.append(ofp.oxm.mpls_label(label))
+    match.oxm_list.append(ofp.oxm.mpls_bos(bos))
+
+    apply_actions = []
+    write_actions = []
+    apply_actions.append(ofp.action.dec_mpls_ttl())
+    if popMPLS == True:
+        apply_actions.append(ofp.action.copy_ttl_in())
+        apply_actions.append(ofp.action.pop_mpls(ethertype))
+    if bos==1 and popL2 == True:
+        apply_actions.append(ofp.action.ofdpa_pop_l2_header())
+        apply_actions.append(ofp.action.ofdpa_pop_cw())
+        apply_actions.append(ofp.action.set_field(ofp.oxm.tunnel_id(tunnel_index + ofp.oxm.TUNNEL_ID_BASE)))
+        # 0x0002nnnn is for UNI interfaces
+        apply_actions.append(ofp.action.set_field(ofp.oxm.exp4ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_MPLS_L2_PORT, value=0x00020000 + of_port)))
+        apply_actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_MPLS_TYPE, value=ofp.oxm.VPWS)))
+
+    write_actions.append(ofp.action.group(action_group_id))
+
+    request = ofp.message.flow_add(
+            table_id=24,
+            cookie=43,
+            match=match,
+            instructions=[
+                    ofp.instruction.apply_actions(actions=apply_actions),
+                    ofp.instruction.write_actions(actions=write_actions),
+                    ofp.instruction.goto_table(goto_table)
+                ],
+            buffer_id=ofp.OFP_NO_BUFFER,
+            priority=1)
+    logging.info("Inserting MPLS flow , label %ld", label)
+    ctrl.message_send(request)
+
+    if send_barrier:
+        do_barrier(ctrl)
+
+    return request
+
+def add_mcast4_routing_flow(ctrl, vlan_id, src_ip, src_ip_mask, dst_ip, action_group_id, send_barrier=False):
+    match = ofp.match()
+    match.oxm_list.append(ofp.oxm.eth_type(0x0800))
+    match.oxm_list.append(ofp.oxm.vlan_vid(0x1000 + vlan_id))
+    if src_ip_mask!=0:
+        match.oxm_list.append(ofp.oxm.ipv4_src_masked(src_ip, src_ip_mask))
+    else:
+        match.oxm_list.append(ofp.oxm.ipv4_src(src_ip))
+
+    match.oxm_list.append(ofp.oxm.ipv4_dst(dst_ip))
+
+    request = ofp.message.flow_add(
+            table_id=40,
+            cookie=42,
+            match=match,
+            instructions=[
+                    ofp.instruction.write_actions(
+                        actions=[ofp.action.group(action_group_id)]),
+                    ofp.instruction.goto_table(60)
+                ],
+            buffer_id=ofp.OFP_NO_BUFFER,
+            priority=1)
+
+    logging.info("Inserting mcast routing flow eth_type %lx, dip %lx, sip %lx, sip_mask %lx",0x0800, dst_ip, src_ip, src_ip_mask)
+    ctrl.message_send(request)
+
+    if send_barrier:
+        do_barrier(ctrl)
+
+    return request
+
+def add_acl_rule(ctrl, eth_type=None, ip_proto=None, vlan_id=None, send_barrier=False):
+    match = ofp.match()
+    if eth_type:
+        match.oxm_list.append(ofp.oxm.eth_type(eth_type))
+    if ip_proto:
+        match.oxm_list.append(ofp.oxm.ip_proto(ip_proto))
+    if vlan_id:
+        match.oxm_list.append(ofp.oxm.vlan_vid(0x1000 + vlan_id))
+    request = ofp.message.flow_add(
+        table_id=60,
+        cookie=42,
+        match=match,
+        instructions=[
+                ofp.instruction.apply_actions(
+                    actions=[ofp.action.output(port=ofp.OFPP_CONTROLLER, max_len=ofp.OFPCML_NO_BUFFER)]
+                    ),
+                ],
+        buffer_id=ofp.OFP_NO_BUFFER,
+        priority=1
+        )
+    output = "Inserting ACL flow: "
+    if eth_type:
+        output += "eth_type {}, ".format(eth_type)
+    if ip_proto:
+        output += "ip_proto {}, ".format(ip_proto)
+    if vlan_id:
+        output += "vlan_id {}".format(vlan_id)
+    logging.info(output)
+
+    ctrl.message_send(request)
+
+    if send_barrier:
+        do_barrier(ctrl)
+
+    return request
+
+#dpctl tcp:192.168.1.1:6633 flow-mod table=28,cmd=add,prio=281 eth_type=0x800,ip_dst=100.0.0.1,ip_proto=6,tcp_dst=5000 write:set_field=ip_dst:10.0.0.1,set_field=tcp_dst:2000,group=0x71000001 goto:60
+def add_dnat_flow(ctrl, eth_type, ip_dst, ip_proto, tcp_dst, set_ip_dst, set_tcp_dst, action_group_id):
+    match = ofp.match()
+    match.oxm_list.append(ofp.oxm.eth_type(eth_type))
+    match.oxm_list.append(ofp.oxm.ipv4_dst(ip_dst))
+    match.oxm_list.append(ofp.oxm.ip_proto(ip_proto))
+    match.oxm_list.append(ofp.oxm.tcp_dst(tcp_dst))
+
+    request = ofp.message.flow_add(
+            table_id=28,
+            cookie=42,
+            match=match,
+            instructions=[
+                    ofp.instruction.write_actions(
+                        actions=[ofp.action.set_field(ofp.oxm.ipv4_dst(set_ip_dst)),
+                                 ofp.action.set_field(ofp.oxm.tcp_dst(set_tcp_dst)),
+                                 ofp.action.group(action_group_id)]),
+                    ofp.instruction.goto_table(60)
+                ],
+            buffer_id=ofp.OFP_NO_BUFFER,
+            priority=1)
+    logging.info("Inserting DNAT flow eth_type %lx, dip %lx, ip_proto %ld, tcp_dst %ld, SetFeild: Dip %lx, tcp_dst %ld, action_gorup=%lx",eth_type, ip_dst, ip_proto, tcp_dst, set_ip_dst, set_tcp_dst, action_group_id)
+    ctrl.message_send(request)
+    return request
+
+#dpctl tcp:192.168.1.1:6633 flow-mod table=29,cmd=add,prio=291 eth_type=0x800,ip_src=10.0.0.1,ip_proto=6,tcp_src=2000 write:set_field=ip_src:100.0.0.1,set_field=tcp_src:5000 goto:30
+def add_snat_flow(ctrl, eth_type, ip_src, ip_proto, tcp_src, set_ip_src, set_tcp_src):
+    match = ofp.match()
+    match.oxm_list.append(ofp.oxm.eth_type(eth_type))
+    match.oxm_list.append(ofp.oxm.ipv4_src(ip_src))
+    match.oxm_list.append(ofp.oxm.ip_proto(ip_proto))
+    match.oxm_list.append(ofp.oxm.tcp_src(tcp_src))
+
+    request = ofp.message.flow_add(
+            table_id=29,
+            cookie=42,
+            match=match,
+            instructions=[
+                    ofp.instruction.write_actions(
+                        actions=[ofp.action.set_field(ofp.oxm.ipv4_src(set_ip_src)),
+                                 ofp.action.set_field(ofp.oxm.tcp_src(set_tcp_src))]),
+                    ofp.instruction.goto_table(30)
+                ],
+            buffer_id=ofp.OFP_NO_BUFFER,
+            priority=1)
+    logging.info("Inserting DNAT flow eth_type %lx, sip %lx, ip_proto %ld, tcp_src %ld, SetFeild: sip %lx, tcp_src %ld",eth_type, ip_src, ip_proto, tcp_src, set_ip_src, set_tcp_src)
+    ctrl.message_send(request)
+    return request
+
+def get_vtap_lport_config_xml(dp_id, lport, phy_port, vlan, vnid, operation='merge'):
+    """
+    Command Example:
+    of-agent vtap 10001 ethernet 1/1 vid 1
+    of-agent vtp 10001 vni 10
+    """
+    if vlan != 0:
+        config_vtap_xml="""
+        <config>
+            <capable-switch xmlns="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
+                <id>capable-switch-1</id>
+                <resources>
+                    <port xc:operation="OPERATION">
+                        <resource-id >LPORT</resource-id>
+                        <features>
+                            <current>
+                              <rate>10Gb</rate>
+                              <medium>fiber</medium>
+                              <pause>symmetric</pause>
+                            </current>
+                            <advertised>
+                              <rate>10Gb</rate>
+                              <rate>100Gb</rate>
+                              <medium>fiber</medium>
+                              <pause>symmetric</pause>
+                            </advertised>
+                            <supported>
+                              <rate>10Gb</rate>
+                              <rate>100Gb</rate>
+                              <medium>fiber</medium>
+                              <pause>symmetric</pause>
+                            </supported>
+                            <advertised-peer>
+                              <rate>10Gb</rate>
+                              <rate>100Gb</rate>
+                              <medium>fiber</medium>
+                              <pause>symmetric</pause>
+                            </advertised-peer>
+                        </features>
+                        <ofdpa10:vtap xmlns:ofdpa10="urn:bcm:ofdpa10:accton01" xc:operation="OPERATION">
+                            <ofdpa10:phy-port>PHY_PORT</ofdpa10:phy-port>
+                            <ofdpa10:vid>VLAN_ID</ofdpa10:vid>
+                            <ofdpa10:vni>VNID</ofdpa10:vni>
+                        </ofdpa10:vtap>
+                    </port>
+              </resources>
+              <logical-switches>
+                  <switch>
+                    <id>DATAPATH_ID</id>
+                    <datapath-id>DATAPATH_ID</datapath-id>
+                    <resources>
+                      <port xc:operation="OPERATION">LPORT</port>
+                    </resources>
+                  </switch>
+              </logical-switches>
+            </capable-switch>
+          </config>
+        """
+    else:
+        config_vtap_xml="""
+        <config>
+            <capable-switch xmlns="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
+                <id>capable-switch-1</id>
+                <resources>
+                    <port xc:operation="OPERATION">
+                        <resource-id >LPORT</resource-id>
+                        <features>
+                            <current>
+                              <rate>10Gb</rate>
+                              <medium>fiber</medium>
+                              <pause>symmetric</pause>
+                            </current>
+                            <advertised>
+                              <rate>10Gb</rate>
+                              <rate>100Gb</rate>
+                              <medium>fiber</medium>
+                              <pause>symmetric</pause>
+                            </advertised>
+                            <supported>
+                              <rate>10Gb</rate>
+                              <rate>100Gb</rate>
+                              <medium>fiber</medium>
+                              <pause>symmetric</pause>
+                            </supported>
+                            <advertised-peer>
+                              <rate>10Gb</rate>
+                              <rate>100Gb</rate>
+                              <medium>fiber</medium>
+                              <pause>symmetric</pause>
+                            </advertised-peer>
+                        </features>
+                        <ofdpa10:vtap xmlns:ofdpa10="urn:bcm:ofdpa10:accton01" xc:operation="OPERATION">
+                            <ofdpa10:phy-port>PHY_PORT</ofdpa10:phy-port>
+                            <ofdpa10:vni>VNID</ofdpa10:vni>
+                        </ofdpa10:vtap>
+                    </port>
+              </resources>
+              <logical-switches>
+                  <switch>
+                    <id>DATAPATH_ID</id>
+                    <datapath-id>DATAPATH_ID</datapath-id>
+                    <resources>
+                      <port xc:operation="OPERATION">LPORT</port>
+                    </resources>
+                  </switch>
+              </logical-switches>
+            </capable-switch>
+          </config>
+        """
+    str_datapath_id_f= "{:016x}".format(dp_id)
+    str_datapath_id=':'.join([str_datapath_id_f[i:i+2] for i in range(0, len(str_datapath_id_f), 2)])
+    config_vtap_xml=config_vtap_xml.replace("DATAPATH_ID", str_datapath_id)
+    config_vtap_xml=config_vtap_xml.replace("LPORT", str(int(lport)))
+    config_vtap_xml=config_vtap_xml.replace("PHY_PORT", str(phy_port))
+    config_vtap_xml=config_vtap_xml.replace("VLAN_ID", str(vlan))
+    config_vtap_xml=config_vtap_xml.replace("VNID", str(vnid))
+    config_vtap_xml=config_vtap_xml.replace("OPERATION", str(operation))
+    return config_vtap_xml
+
+def get_vtep_lport_config_xml(dp_id, lport, src_ip, dst_ip, next_hop_id, vnid, udp_src_port=6633, ttl=25, operation='merge'):
+    """
+    Command Example:
+    of-agent vtep 10002 source user-input-src-ip destination user-input-dst-ip udp-source-port 6633 nexthop 2 ttl 25
+    of-agent vtp 10001 vni 10
+    """
+
+    config_vtep_xml="""
+        <config>
+          <capable-switch xmlns="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
+            <id>capable-switch-1</id>
+            <resources>
+             <port xc:operation="OPERATION">
+               <resource-id>LPORT</resource-id>
+                 <features>
+                   <current>
+                     <rate>10Gb</rate>
+                     <medium>fiber</medium>
+                     <pause>symmetric</pause>
+                   </current>
+                   <advertised>
+                     <rate>10Gb</rate>
+                     <rate>100Gb</rate>
+                     <medium>fiber</medium>
+                     <pause>symmetric</pause>
+                   </advertised>
+                   <supported>
+                     <rate>10Gb</rate>
+                     <rate>100Gb</rate>
+                     <medium>fiber</medium>
+                     <pause>symmetric</pause>
+                   </supported>
+                   <advertised-peer>
+                     <rate>10Gb</rate>
+                     <rate>100Gb</rate>
+                     <medium>fiber</medium>
+                     <pause>symmetric</pause>
+                   </advertised-peer>
+                </features>
+              <ofdpa10:vtep xmlns:ofdpa10="urn:bcm:ofdpa10:accton01">
+                <ofdpa10:src-ip>SRC_IP</ofdpa10:src-ip>
+                <ofdpa10:dest-ip>DST_IP</ofdpa10:dest-ip>
+                <ofdpa10:udp-src-port>UDP_SRC_PORT</ofdpa10:udp-src-port>
+                <ofdpa10:vni xc:operation="OPERATION">
+                    <ofdpa10:id>VNID</ofdpa10:id>
+                </ofdpa10:vni>
+                <ofdpa10:nexthop-id>NEXT_HOP_ID</ofdpa10:nexthop-id>
+                <ofdpa10:ttl>TTL</ofdpa10:ttl>
+              </ofdpa10:vtep>
+             </port>
+            </resources>
+            <logical-switches>
+                <switch>
+                  <id>DATAPATH_ID</id>
+                  <datapath-id>DATAPATH_ID</datapath-id>
+                  <resources>
+                    <port xc:operation="OPERATION">LPORT</port>
+                  </resources>
+                </switch>
+            </logical-switches>
+          </capable-switch>
+        </config>
+    """
+    str_datapath_id_f= "{:016x}".format(dp_id)
+    str_datapath_id=':'.join([str_datapath_id_f[i:i+2] for i in range(0, len(str_datapath_id_f), 2)])
+    config_vtep_xml=config_vtep_xml.replace("DATAPATH_ID", str_datapath_id)
+    config_vtep_xml=config_vtep_xml.replace("LPORT", str(int(lport)))
+    config_vtep_xml=config_vtep_xml.replace("SRC_IP", str(src_ip))
+    config_vtep_xml=config_vtep_xml.replace("DST_IP", str(dst_ip))
+    config_vtep_xml=config_vtep_xml.replace("UDP_SRC_PORT", str(udp_src_port))
+    config_vtep_xml=config_vtep_xml.replace("NEXT_HOP_ID", str(next_hop_id))
+    config_vtep_xml=config_vtep_xml.replace("TTL", str(ttl))
+    config_vtep_xml=config_vtep_xml.replace("VNID", str(vnid))
+    config_vtep_xml=config_vtep_xml.replace("OPERATION", str(operation))
+
+    return config_vtep_xml
+
+def get_next_hop_config_xml(next_hop_id, dst_mac, phy_port, vlan, operation='merge'):
+    #of-agent nexthop 2 destination user-input-dst-mac ethernet 1/2 vid 2
+    config_nexthop_xml="""
+      <config>
+          <of11-config:capable-switch xmlns:of11-config="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
+            <ofdpa10:next-hop xmlns:ofdpa10="urn:bcm:ofdpa10:accton01"  xc:operation="OPERATION">
+              <ofdpa10:id>NEXT_HOP_ID</ofdpa10:id>
+              <ofdpa10:dest-mac>DST_MAC</ofdpa10:dest-mac>
+              <ofdpa10:phy-port>PHY_PORT</ofdpa10:phy-port>
+              <ofdpa10:vid>VLAN_ID</ofdpa10:vid>
+            </ofdpa10:next-hop>
+          </of11-config:capable-switch>
+      </config>
+      """
+    config_nexthop_xml=config_nexthop_xml.replace("VLAN_ID", str(vlan))
+    config_nexthop_xml=config_nexthop_xml.replace("PHY_PORT", str(phy_port))
+    config_nexthop_xml=config_nexthop_xml.replace("NEXT_HOP_ID", str(next_hop_id))
+    config_nexthop_xml=config_nexthop_xml.replace("DST_MAC", str(dst_mac))
+    config_nexthop_xml=config_nexthop_xml.replace("OPERATION", str(operation))
+    return config_nexthop_xml
+
+def get_vni_config_xml(vni_id, mcast_ipv4, next_hop_id, operation='merge'):
+    #of-agent vni 10 multicast 224.1.1.1 nexthop 20
+    if mcast_ipv4!=None:
+        config_vni_xml="""
+          <config>
+              <of11-config:capable-switch xmlns:of11-config="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
+                <ofdpa10:vni xmlns:ofdpa10="urn:bcm:ofdpa10:accton01" xc:operation="OPERATION">
+                  <ofdpa10:id>VNID</ofdpa10:id>
+                  <ofdpa10:vni-multicast-group>MCAST_IP</ofdpa10:vni-multicast-group>
+                  <ofdpa10:multicast-group-nexthop-id>NEXT_HOP_ID</ofdpa10:multicast-group-nexthop-id>
+                </ofdpa10:vni>
+              </of11-config:capable-switch>
+          </config>
+          """
+        config_vni_xml=config_vni_xml.replace("NEXT_HOP_ID", str(next_hop_id))
+        config_vni_xml=config_vni_xml.replace("MCAST_IP", str(mcast_ipv4))
+    else:
+        config_vni_xml="""
+          <config>
+              <of11-config:capable-switch xmlns:of11-config="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
+                <ofdpa10:vni xmlns:ofdpa10="urn:bcm:ofdpa10:accton01" xc:operation="OPERATION">
+                  <ofdpa10:id>VNID</ofdpa10:id>
+                </ofdpa10:vni>
+              </of11-config:capable-switch>
+          </config>
+          """
+
+    config_vni_xml=config_vni_xml.replace("VNID", str(vni_id))
+    config_vni_xml=config_vni_xml.replace("OPERATION", str(operation))
+    return config_vni_xml
+
+def get_featureReplay(self):
+    req = ofp.message.features_request()
+    res, raw = self.controller.transact(req)
+    self.assertIsNotNone(res, "Did not receive a response from the DUT.")
+    self.assertEqual(res.type, ofp.OFPT_FEATURES_REPLY,
+                 ("Unexpected packet type %d received in response to "
+                  "OFPT_FEATURES_REQUEST") % res.type)
+    return res
+
+def send_edit_config(switch_ip, xml, target='runing'):
+    NETCONF_ACCOUNT="netconfuser"
+    NETCONF_PASSWD="netconfuser"
+    with manager.connect_ssh(host=switch_ip, port=830, username=NETCONF_ACCOUNT, password=NETCONF_PASSWD, hostkey_verify=False ) as m:
+        try:
+            m.edit_config(target='running',
+                      config=xml,
+                      default_operation='merge',
+                      error_option='stop-on-error')
+
+        except Exception as e:
+            logging.info("Fail to set xml %s", xml)
+            return False
+
+    #return m.get_config(source='running').data_xml
+    return True
+
+def send_delete_config(switch_ip, xml, target='runing'):
+    NETCONF_ACCOUNT="netconfuser"
+    NETCONF_PASSWD="netconfuser"
+    with manager.connect_ssh(host=switch_ip, port=830, username=NETCONF_ACCOUNT, password=NETCONF_PASSWD, hostkey_verify=False ) as m:
+        try:
+            m.edit_config(target='running',
+                      config=xml,
+                      default_operation='delete',
+                      error_option='stop-on-error')
+
+        except Exception as e:
+            logging.info("Fail to set xml %s", xml)
+            return False
+
+    #return m.get_config(source='running').data_xml
+    return True
+
+def get_edit_config(switch_ip, target='runing'):
+    NETCONF_ACCOUNT="netconfuser"
+    NETCONF_PASSWD="netconfuser"
+    with manager.connect_ssh(host=switch_ip, port=830, username=NETCONF_ACCOUNT, password=NETCONF_PASSWD, hostkey_verify=False ) as m:
+        return m.get_config(source='running').data_xml
+
+
+"""
+MPLS
+"""
+
+OFDPA_MPLS_SUBTYPE_SHIFT=24
+OFDPA_MPLS_GROUP_SUBTYPE_L2_VPN_LABEL=1
+OFDPA_MPLS_GROUP_SUBTYPE_L3_VPN_LABEL=2
+OFDPA_MPLS_GROUP_SUBTYPE_TUNNEL_LABEL1=3
+OFDPA_MPLS_GROUP_SUBTYPE_TUNNEL_LABEL2=4
+OFDPA_MPLS_GROUP_SUBTYPE_SWAP_LABEL=5
+OFDPA_MPLS_GROUP_SUBTYPE_FAST_FAILOVER_GROUP=6
+OFDPA_MPLS_GROUP_SUBTYPE_ECMP=8
+OFDPA_MPLS_GROUP_SUBTYPE_L2_TAG=10
+
+
+
+
+def encode_mpls_interface_group_id(subtype, index):
+    index=index&0x00ffffff
+    assert(subtype==0)
+    return index + (9 << OFDPA_GROUP_TYPE_SHIFT)+(subtype<<OFDPA_MPLS_SUBTYPE_SHIFT)
+
+def encode_mpls_label_group_id(subtype, index):
+    index=index&0x00ffffff
+    assert(subtype <=5 or subtype==0)
+    #1: l2 vpn label
+    #2: l3 vpn label
+    #3: mpls tunnel label 1
+    #4: mpls tunnel lable 2
+    #5: mpls swap label
+    return index + (9 << OFDPA_GROUP_TYPE_SHIFT)+(subtype<<OFDPA_MPLS_SUBTYPE_SHIFT)
+
+def encode_mpls_forwarding_group_id(subtype, index):
+    index=index&0x00ffffff
+    assert(subtype==6 or subtype==8 or subtype==10)
+    return index + (10 << OFDPA_GROUP_TYPE_SHIFT)+(subtype<<OFDPA_MPLS_SUBTYPE_SHIFT)
+
+
+def add_mpls_intf_group(ctrl, ref_gid, dst_mac, src_mac, vid, index, subtype=0, send_barrier=False, add=True):
+    action=[]
+    action.append(ofp.action.set_field(ofp.oxm.eth_src(src_mac)))
+    action.append(ofp.action.set_field(ofp.oxm.eth_dst(dst_mac)))
+    action.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vid)))
+    action.append(ofp.action.group(ref_gid))
+
+    buckets = [ofp.bucket(actions=action)]
+
+    mpls_group_id =encode_mpls_interface_group_id(subtype, index)
+    if add:
+        request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
+                                        group_id=mpls_group_id,
+                                        buckets=buckets
+                                       )
+    else:
+        request = ofp.message.group_modify(group_type=ofp.OFPGT_INDIRECT,
+                                        group_id=mpls_group_id,
+                                        buckets=buckets
+                                       )
+
+
+    logging.debug("Adding MPLS interface group %02x, src_mac %s , dst_mac %s , vid %d", mpls_group_id, src_mac, dst_mac, vid)
+    ctrl.message_send(request)
+
+    if send_barrier:
+        do_barrier(ctrl)
+    return mpls_group_id, request
+
+def add_mpls_tunnel_label_group(
+    ctrl,
+    ref_gid,
+    subtype,
+    index,
+    label,
+    ):
+
+    action=[]
+    action.append(ofp.action.push_mpls(0x8847))
+    action.append(ofp.action.set_field(ofp.oxm.mpls_label(label)))
+    action.append(ofp.action.group(ref_gid))
+    buckets = [ofp.bucket(actions=action)]
+
+    mpls_group_id = encode_mpls_label_group_id(subtype, index)
+    request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
+                                    group_id=mpls_group_id,
+                                    buckets=buckets
+                                   )
+    ctrl.message_send(request)
+
+    return mpls_group_id, request
+
+def add_mpls_swap_label_group(
+    ctrl,
+    ref_gid,
+    subtype,
+    index,
+    label,
+    ):
+
+    action=[]
+    action.append(ofp.action.set_field(ofp.oxm.mpls_label(label)))
+    action.append(ofp.action.group(ref_gid))
+    buckets = [ofp.bucket(actions=action)]
+
+    mpls_group_id = encode_mpls_label_group_id(subtype, index)
+    request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
+                                    group_id=mpls_group_id,
+                                    buckets=buckets
+                                   )
+    logging.debug("Adding MPLS Swap group %02x, label %d", mpls_group_id, label)
+    ctrl.message_send(request)
+
+    return mpls_group_id, request
+
+def add_mpls_label_group(ctrl, subtype, index, ref_gid,
+                         lmep_id=-1,
+                         qos_index=-1,
+                         push_l2_header=False,
+                         push_vlan=False,
+                         push_mpls_header=False,
+                         push_cw=False,
+                         set_mpls_label=None,
+                         set_bos=None,
+                         set_tc=None,
+                         set_tc_from_table=False,
+                         cpy_tc_outward=False,
+                         set_ttl=None,
+                         cpy_ttl_outward=False,
+                         oam_lm_tx_count=False,
+                         set_pri_from_table=False,
+                         send_barrier=False
+                         ):
+    """
+    @ref_gid: only can be mpls intf group or mpls tunnel label 1/2 group
+    """
+    action=[]
+
+    if push_vlan== True:
+        action.append(ofp.action.push_vlan(0x8100))
+    if push_mpls_header== True:
+        action.append(ofp.action.push_mpls(0x8847))
+    if set_mpls_label != None:
+        action.append(ofp.action.set_field(ofp.oxm.mpls_label(set_mpls_label)))
+    if set_bos != None:
+        action.append(ofp.action.set_field(ofp.oxm.mpls_bos(set_bos)))
+    if set_tc != None:
+        assert(set_tc_from_table==False)
+        action.append(ofp.action.set_field(ofp.oxm.mpls_tc(set_tc)))
+    if set_ttl != None:
+        action.append(ofp.action.set_mpls_ttl(set_ttl))
+    if cpy_ttl_outward == True:
+        action.append(ofp.action.copy_ttl_out())
+    """
+    ofdpa experimenter
+    """
+    if push_l2_header== True:
+        action.append(ofp.action.ofdpa_push_l2_header())
+    if set_tc_from_table== True:
+        assert(qos_index>=0)
+        assert(set_tc == None)
+        action.append(ofp.action.ofdpa_set_tc_from_table(qos_index))
+    if cpy_tc_outward == True:
+        action.append(ofp.action.ofdpa_copy_tc_out())
+    if oam_lm_tx_count == True:
+        assert(qos_index>=0 and lmep_id>=0)
+        action.append(ofp.action.ofdpa_oam_lm_tx_count(lmep_id, qos_index))
+    if set_pri_from_table == True:
+        assert(qos_index>=0)
+        action.append(ofp.action.ofdpa_set_qos_from_table(qos_index))
+    if push_cw == True:
+        action.append(ofp.action.ofdpa_push_cw())
+
+    action.append(ofp.action.group(ref_gid))
+    buckets = [ofp.bucket(actions=action)]
+
+    mpls_group_id = encode_mpls_label_group_id(subtype, index)
+    request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
+                                    group_id=mpls_group_id,
+                                    buckets=buckets
+                                   )
+    ctrl.message_send(request)
+
+    if send_barrier:
+        do_barrier(ctrl)
+
+    return mpls_group_id, request
+
+def add_mpls_l2_port_flow(ctrl, of_port, mpls_l2_port, tunnel_index, ref_gid, qos_index=0, goto=MPLS_L2_PORT_PCP_TRUST_FLOW_TABLE):
+    """
+    Only action is Group, which must indicate one of:
+    MPLS L2 VPN Label or Fast Failover Protection Group.
+    ref_gid contains this information
+    """
+
+    match = ofp.match()
+
+    write_actions = []
+    write_actions.append(ofp.action.group(ref_gid))
+    apply_actions = []
+
+    if goto==MPLS_L2_PORT_PCP_TRUST_FLOW_TABLE:
+        tunnel_id = tunnel_index + ofp.oxm.TUNNEL_ID_BASE
+        match.oxm_list.append(ofp.oxm.exp4ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_MPLS_L2_PORT, value=0x00000000 + of_port))
+        match.oxm_list.append(ofp.oxm.tunnel_id(tunnel_index + ofp.oxm.TUNNEL_ID_BASE))
+        assert(qos_index>=0)
+        apply_actions.append(ofp.action.set_field(ofp.oxm.exp1ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_QOS_INDEX, value=qos_index)))
+
+        request = ofp.message.flow_add(
+            table_id=MPLS_L2_PORT_FLOW_TABLE,
+            cookie=42,
+            match=match,
+            instructions=[
+                    ofp.instruction.apply_actions(actions=apply_actions),
+                    ofp.instruction.write_actions(actions=write_actions),
+                    ofp.instruction.goto_table(goto)
+                    ],
+            buffer_id=ofp.OFP_NO_BUFFER,
+            priority=1)
+        logging.info("Inserting flow for Pseudowire Initiation %d mpls_l2_port, %d tunnel_id, action %x group and go to table %d", mpls_l2_port, tunnel_id, ref_gid, MPLS_L2_PORT_DSCP_TRUST_FLOW_TABLE)
+        ctrl.message_send(request)
+
+    if goto==ACL_FLOW_TABLE:
+        tunnel_id = tunnel_index + ofp.oxm.TUNNEL_ID_BASE
+        match.oxm_list.append(ofp.oxm.exp4ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_MPLS_L2_PORT, value=0x00000000 + of_port))
+        match.oxm_list.append(ofp.oxm.tunnel_id(tunnel_index + ofp.oxm.TUNNEL_ID_BASE_CROSS_CONNECT))
+        request = ofp.message.flow_add(
+            table_id=MPLS_L2_PORT_FLOW_TABLE,
+            cookie=42,
+            match=match,
+            instructions=[
+                    ofp.instruction.apply_actions(actions=apply_actions),
+                    ofp.instruction.write_actions(actions=write_actions),
+                    ofp.instruction.goto_table(goto)
+                    ],
+            buffer_id=ofp.OFP_NO_BUFFER,
+            priority=1)
+        logging.info("Inserting flow for VLAN Cross Connect %d mpls_l2_port, %d tunnel_id, action %x group and go to table %d", mpls_l2_port, tunnel_id, ref_gid, ACL_FLOW_TABLE)
+        ctrl.message_send(request)
+
+    return request
+
+def add_mpls_forwarding_group(ctrl, subtype, index, ref_gids,
+                              watch_port=None,
+                              watch_group=ofp.OFPP_ANY,
+                              push_vlan=None,
+                              pop_vlan=None,
+                              set_vid=None):
+    assert(subtype == OFDPA_MPLS_GROUP_SUBTYPE_FAST_FAILOVER_GROUP
+           or subtype == OFDPA_MPLS_GROUP_SUBTYPE_ECMP
+           or subtype == OFDPA_MPLS_GROUP_SUBTYPE_L2_TAG)
+
+    buckets=[]
+    if subtype == OFDPA_MPLS_GROUP_SUBTYPE_FAST_FAILOVER_GROUP:
+        group_type = ofp.OFPGT_FF
+        for gid in ref_gids:
+            action=[]
+            action.append(ofp.action.group(gid))
+            buckets.append(ofp.bucket(watch_port=watch_port, watch_group=watch_group,actions=action))
+
+    elif subtype == OFDPA_MPLS_GROUP_SUBTYPE_ECMP:
+        group_type = ofp.OFPGT_SELECT
+        for gid in ref_gids:
+            action=[]
+            action.append(ofp.action.group(gid))
+            buckets.append(ofp.bucket(actions=action))
+
+    elif subtype == OFDPA_MPLS_GROUP_SUBTYPE_L2_TAG:
+        group_type = ofp.OFPGT_INDIRECT
+        action=[]
+        if set_vid!=None:
+            action.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+set_vid)))
+        if push_vlan!=None:
+            action.append(ofp.action.push_vlan(push_vlan))
+        if pop_vlan!=None:
+            action.append(ofp.action.pop_vlan())
+            action.append(ofp.action.group(ref_gids[0]))
+            buckets.append(ofp.bucket(actions=action))
+
+    mpls_group_id = encode_mpls_forwarding_group_id(subtype, index)
+    request = ofp.message.group_add(group_type=group_type,
+                                    group_id=mpls_group_id,
+                                    buckets=buckets
+                                   )
+    ctrl.message_send(request)
+    return mpls_group_id, request
+
+def add_one_egress_vlan_tpid_table_flow(ctrl, of_port):
+    # Used for changing ethertype of outer vlan header to 0x88a8
+
+    match = ofp.match()
+    match.oxm_list.append(ofp.oxm.exp4ByteValue(ofp.oxm.OFDPA_EXP_TYPE_ACTSET_OUTPUT, of_port, ONF_EXPERIMENTER_ID))
+    match.oxm_list.append(ofp.oxm.vlan_vid_masked(ofp.OFPVID_PRESENT, ofp.OFPVID_PRESENT))
+
+    actions = []
+    actions.append(ofp.action.copy_field(
+        12, 0, 0, ['\x80\x00\x0c\x02', ofp.oxm.exp4ByteReg(oxm_field = 1).pack()])) # VLAN_VID, PACKET_REG(1)
+    actions.append(ofp.action.pop_vlan())
+    actions.append(ofp.action.push_vlan(0x88a8))
+    actions.append(ofp.action.copy_field(
+        12, 0, 0, [ofp.oxm.exp4ByteReg(oxm_field = 1).pack(), '\x80\x00\x0c\x02'])) # PACKET_REG(1), VLAN_VID
+
+    request = ofp.message.flow_add(
+        table_id=EGRESS_TPID_FLOW_TABLE,
+        cookie=42,
+        match=match,
+        instructions=[
+            ofp.instruction.apply_actions(
+                actions=actions
+            ),
+        ],
+        priority=0)
+
+    ctrl.message_send(request)
+
+    return
+
+"""
+display
+"""
+def print_current_table_flow_stat(ctrl, table_id=0xff):
+    stat_req=ofp.message.flow_stats_request()
+    response, pkt = ctrl.transact(stat_req)
+    if response == None:
+        print "no response"
+        return None
+    print len(response.entries)
+    for obj in response.entries:
+        print "match ", obj.match
+        print "cookie", obj.cookie
+        print "priority", obj.priority
+        print "idle_timeout", obj.idle_timeout
+        print "hard_timeout", obj.hard_timeout
+        #obj.actions
+        print "packet count: %lx"%obj.packet_count
+
diff --git a/Fabric/Utilities/accton/acl_flow.py b/Fabric/Utilities/accton/acl_flow.py
new file mode 100755
index 0000000..c055ba1
--- /dev/null
+++ b/Fabric/Utilities/accton/acl_flow.py
@@ -0,0 +1,71 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+import logging

+

+from oftest import config

+import oftest.base_tests as base_tests

+import ofp

+from oftest.testutils import *

+from accton_util import *

+

+

+class NoVlanOnlyAclOutputPort(base_tests.SimpleDataPlane):

+    """

+    In OFDPA, ACL can save the packet it was dropped vlan table

+    """

+    def runTest(self):

+        ports = sorted(config["port_map"].keys())

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)    

+        input_port=ports[0]

+        output_port=ports[1]

+        vlan_id = 10

+        dmac = [0x00, 0x12, 0x34, 0x56, 0x78, 0x9a]

+        gid, req_msg = add_one_l2_interface_group(self.controller, port=output_port, vlan_id=vlan_id, is_tagged=True, send_barrier=False)

+        #add ACL flow to output port

+        match = ofp.match()

+        match.oxm_list.append(ofp.oxm.in_port(input_port))

+        match.oxm_list.append(ofp.oxm.eth_dst(dmac))

+        match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlan_id))

+        request = ofp.message.flow_add(

+            table_id=60,

+            cookie=42,

+            match=match,

+            instructions=[

+                ofp.instruction.write_actions(

+                    actions=[

+                        ofp.action.group(gid)]

+                    )

+            ],

+            priority=1)

+        #install flow

+        self.controller.message_send(request)        

+

+        dmac_str = convertMACtoStr(dmac)

+        #send packet

+        parsed_pkt = simple_tcp_packet(eth_dst=dmac_str, vlan_vid=vlan_id, dl_vlan_enable=True)

+        self.dataplane.send(input_port, str(parsed_pkt))

+        #verify packet

+        verify_packet(self, str(parsed_pkt), output_port)        

+

+        

+        

+        

+        

+        

+        

+        
\ No newline at end of file
diff --git a/Fabric/Utilities/accton/epr.py b/Fabric/Utilities/accton/epr.py
new file mode 100755
index 0000000..c13a3d7
--- /dev/null
+++ b/Fabric/Utilities/accton/epr.py
@@ -0,0 +1,105 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+import logging

+

+from oftest import config

+import oftest.base_tests as base_tests

+import ofp

+from oftest.testutils import *

+from accton_util import *

+

+"""

+This file test case is copied from NTC EPR bug

+"""

+

+class pvidClear(base_tests.SimpleDataPlane):

+    """

+    AOS5700-54X-00620

+    """

+    def runTest(self):

+        ports = sorted(config["port_map"].keys())

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)    

+        port1=ports[0]

+        port2=ports[1]

+        

+        vlan_id = 10

+

+        gid_p1, req_msg_p1 = add_one_l2_interface_group(self.controller, port=port1, vlan_id=vlan_id, is_tagged=False, send_barrier=False)

+        gid_p2, req_msg_p2 = add_one_l2_interface_group(self.controller, port=port2, vlan_id=vlan_id, is_tagged=False, send_barrier=False)

+        #add ACL flow, in port1 out port2

+        match = ofp.match()

+        match.oxm_list.append(ofp.oxm.in_port(port1))

+        request = ofp.message.flow_add(

+            table_id=60,

+            cookie=42,

+            match=match,

+            instructions=[

+                ofp.instruction.write_actions(

+                    actions=[

+                        ofp.action.group(gid_p2)]

+                    )

+            ],

+            priority=1)

+        #install flow

+        self.controller.message_send(request)        

+        #add ACL flow, in port2 out port1

+        match = ofp.match()

+        match.oxm_list.append(ofp.oxm.in_port(port2))

+        request = ofp.message.flow_add(

+            table_id=60,

+            cookie=42,

+            match=match,

+            instructions=[

+                ofp.instruction.write_actions(

+                    actions=[

+                        ofp.action.group(gid_p1)]

+                    )

+            ],

+            priority=1)

+        #install flow

+        self.controller.message_send(request)    

+        

+        #send packet and verify packet

+        parsed_pkt = simple_tcp_packet()

+        self.dataplane.send(port1, str(parsed_pkt))

+        verify_no_packet(self, str(parsed_pkt), port2)         

+        self.dataplane.send(port2, str(parsed_pkt))        

+        verify_no_packet(self, str(parsed_pkt), port1)        

+

+        

+        #add vlan flow table

+        add_vlan_table_flow(self.controller, [port1, port2], vlan_id=vlan_id, flag=VLAN_TABLE_FLAG_ONLY_UNTAG)

+        #send packet and verify packet

+        parsed_pkt = simple_tcp_packet()

+        self.dataplane.send(port1, str(parsed_pkt))

+        verify_packet(self, str(parsed_pkt), port2)        

+        self.dataplane.send(port2, str(parsed_pkt))        

+        verify_packet(self, str(parsed_pkt), port1)

+         

+        #remove vlan table flow        

+        del_vlan_table_flow(self.controller, [port1, port2], vlan_id=vlan_id, flag=VLAN_TABLE_FLAG_ONLY_UNTAG)

+        #send packet and verify packet

+        parsed_pkt = simple_tcp_packet()

+        self.dataplane.send(port1, str(parsed_pkt))

+        verify_no_packet(self, str(parsed_pkt), port2)

+        self.dataplane.send(port2, str(parsed_pkt))

+        verify_no_packet(self, str(parsed_pkt), port1)

+        

+        

+        

+            

diff --git a/Fabric/Utilities/accton/flow_test.py b/Fabric/Utilities/accton/flow_test.py
new file mode 100755
index 0000000..348d8ab
--- /dev/null
+++ b/Fabric/Utilities/accton/flow_test.py
@@ -0,0 +1,1040 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+"""

+Flow Test

+

+Test each flow table can set entry, and packet rx correctly.

+"""

+

+import logging

+

+from oftest import config

+import oftest.base_tests as base_tests

+import ofp

+from oftest.testutils import *

+from accton_util import *

+

+class L2McastFlow(base_tests.SimpleDataPlane):

+    """

+    Test output function for an exact-match flow

+

+    Add some multicast flows

+    Then, for all ports, verifies that sending a matching packet

+    to a multicast match results in an output to all ports.

+    """

+    def runTest(self):

+        ports = sorted(config["port_map"].keys())

+

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        # table 10: vlan

+        # send to table 20

+        add_vlan_table_flow(self.controller, config["port_map"].keys(), 1)

+

+        # group table

+        # set up untag groups for each port

+        add_l2_interface_grouop(self.controller, config["port_map"].keys(), 1,  False, False)

+

+        # set up multicast group

+        add_l2_mcast_group(self.controller, config["port_map"].keys(), 1, 1)

+        

+        test_macs = [[0x01, 0x00, 0x5e, 0x0f, 0xff, 0xff]]

+

+        for test_mac in test_macs:

+            group_id = encode_l2_mcast_group_id(1, 1)

+            add_bridge_flow(self.controller, test_mac, 1, group_id, True)

+

+        for test_mac in test_macs:

+            mactest = ':'.join(['%02X' % x for x in test_mac])

+

+            for in_port in ports:

+                # change dest based on port number

+                parsed_pkt = simple_tcp_packet(eth_dst=mactest)

+                pkt = str(parsed_pkt)

+                logging.info("OutputExact test, from port %d to mac %s", in_port, mactest)

+                self.dataplane.send(in_port, pkt)

+

+                for ofport in ports:

+                    if ofport == in_port: #tx port won't rx packet, unless L3 mcast routing

+                        continue

+                    verify_packet(self, pkt, ofport)

+                verify_no_other_packets(self)

+

+class L2UnicastFlow(base_tests.SimpleDataPlane):

+    """

+    Test output function for an exact-match flow

+

+    For each port A, adds a flow directing matching packets to that port.

+    Then, for all other ports B != A, verifies that sending a matching packet

+    to B results in an output to A.

+    """

+    def runTest(self):

+        ports = sorted(config["port_map"].keys())

+

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+        # table 10: vlan

+        # send to table 20

+        #add_vlan_table_flow(self.controller, config["port_map"].keys(),1)

+

+        # group table

+        # set up tag groups for each port

+        add_l2_interface_group(self.controller, config["port_map"].keys(), 1, True, 1)

+

+        for port in ports:

+            add_one_vlan_table_flow(self.controller, port, 1)

+            group_id = encode_l2_interface_group_id(1, port)

+            add_bridge_flow(self.controller, [0x00, 0x12, 0x34, 0x56, 0x78, port], 1, group_id, True)

+        do_barrier(self.controller)

+

+        for out_port in ports:

+            # change dest based on port number

+            mac_dst= '00:12:34:56:78:%02X' % out_port

+

+            for in_port in ports:

+                if in_port == out_port:

+                    continue

+                # change source based on port number to avoid packet-ins from learning     

+                mac_src= '00:12:34:56:79:%02X' % in_port 

+                parsed_pkt = simple_tcp_packet(dl_vlan_enable=True, vlan_vid=1, eth_dst=mac_dst, eth_src=mac_src)

+                pkt = str(parsed_pkt)

+                logging.info("OutputExact test, ports %d to %d", in_port, out_port)

+                self.dataplane.send(in_port, pkt)

+

+                for ofport in ports:

+                    if ofport in [out_port]:

+                        verify_packet(self, pkt, ofport)

+                    else:

+                        verify_no_packet(self, pkt, ofport)

+                        

+                verify_no_other_packets(self)

+

+class L2Flood(base_tests.SimpleDataPlane):

+    """

+    Test L2 unknown unicast flooding and broadcast flood

+    """

+    def runTest(self):

+        ports = sorted(config["port_map"].keys())

+

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+        # table 10: vlan

+        # send to table 20

+        add_vlan_table_flow(self.controller, ports, 1)

+

+        # group table

+        # set up untag groups for each port

+        add_l2_interface_grouop(self.controller, ports, 1,  False, 1)

+

+        input_port = ports.pop()

+        flood_ports= ports

+    

+        #no fllod group create, veriy all drop

+        parsed_pkt = simple_tcp_packet(eth_dst='00:12:34:56:78:9a')

+        pkt = str(parsed_pkt)

+        self.dataplane.send(input_port, pkt)

+        verify_no_other_packets(self)

+        parsed_pkt = simple_tcp_packet(eth_dst='FF:FF:FF:FF:FF:FF')

+        pkt = str(parsed_pkt)

+        self.dataplane.send(input_port, pkt)

+        verify_no_other_packets(self)        

+        #add flood groupo    

+        msg=add_l2_flood_group(self.controller, flood_ports, 1, 1)

+        add_bridge_flow(self.controller, None, 1, msg.group_id, True)

+        #verify flood 

+        parsed_pkt = simple_tcp_packet(eth_dst='00:12:34:56:78:9a')

+        pkt = str(parsed_pkt)

+        self.dataplane.send(input_port, pkt)

+        for ofport in flood_ports:

+            verify_packet(self, pkt, ofport)

+

+        verify_no_other_packets(self)

+               

+        for ofport in flood_ports:

+            self.dataplane.send(ofport, pkt)

+            #self won't rx packet

+            verify_no_packet(self, pkt, ofport)

+            #others will rx packet

+            tmp_ports=[]

+            for tmp in flood_ports:

+                if tmp != ofport:

+                    tmp_ports.append(tmp)                

+            verify_packets(self, pkt, tmp_ports)

+            

+        verify_no_other_packets(self)

+

+        parsed_pkt = simple_tcp_packet(eth_dst='FF:FF:FF:FF:FF:FF')

+        pkt = str(parsed_pkt)

+        self.dataplane.send(input_port, pkt)

+        for ofport in flood_ports:

+            verify_packet(self, pkt, ofport)        

+        

+class PacketInMiss(base_tests.SimpleDataPlane):

+    """

+    Test packet in function for a table-miss flow

+

+    Send a packet to each dataplane port and verify that a packet

+    in message is received from the controller for each

+    

+    NOTE: Verify This case the oft option shall not use --switch-ip

+    """

+

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+        

+        parsed_pkt = simple_tcp_packet(pktlen=100)

+        parsed_vlan_pkt = simple_tcp_packet(pktlen=104, 

+                      vlan_vid=0x1001, dl_vlan_enable=True)

+        pkt = str(parsed_pkt)

+        vlan_pkt = str(parsed_vlan_pkt)

+        # table 10: vlan

+        # send to table 20

+        add_vlan_table_flow(self.controller, config["port_map"].keys(), 1)

+

+        # group table

+        # set up untag groups for each port

+        add_l2_interface_grouop(self.controller, config["port_map"].keys(), 1,  False, 1)

+

+        # create match

+        match = ofp.match()

+        match.oxm_list.append(ofp.oxm.vlan_vid(0x1001))

+        request = ofp.message.flow_add(

+            table_id=60,

+            cookie=42,

+            match=match,

+            instructions=[

+                ofp.instruction.apply_actions(

+                    actions=[

+                        ofp.action.output(

+                            port=ofp.OFPP_CONTROLLER,

+                            max_len=ofp.OFPCML_NO_BUFFER)]),

+            ],

+            buffer_id=ofp.OFP_NO_BUFFER,

+            priority=1)

+

+        logging.info("Inserting packet in flow to controller")

+        self.controller.message_send(request)

+        do_barrier(self.controller)

+

+        for of_port in config["port_map"].keys():

+            logging.info("PacketInMiss test, port %d", of_port)

+            self.dataplane.send(of_port, pkt)

+

+            #AOS current packet in will not have vlan tag

+            if config["cicada_poject"]:

+                verify_packet_in(self, vlan_pkt, of_port, ofp.OFPR_ACTION)

+            else:

+                verify_packet_in(self, pkt, of_port, ofp.OFPR_ACTION)

+

+            verify_no_other_packets(self)

+

+class PacketOut(base_tests.SimpleDataPlane):

+    """

+    Verify action Flood, ALL, in port

+    """

+

+    def runTest(self):

+        if config["cicada_poject"]:

+            pass

+            

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+        

+        parsed_pkt = simple_tcp_packet(pktlen=100)

+        parsed_vlan_pkt = simple_tcp_packet(pktlen=104, 

+                      vlan_vid=0x1002, dl_vlan_enable=True)

+                      

+        pkt = str(parsed_pkt)

+        vlan_pkt = str(parsed_vlan_pkt)

+       

+        

+        #packet out flood, untag packet

+        self.controller.message_send(ofp.message.packet_out(in_port=ofp.OFPP_CONTROLLER,

+                                                            buffer_id=ofp.OFP_NO_BUFFER,

+                                                            actions=[ofp.action.output(

+                                                                     port=ofp.OFPP_FLOOD)],

+                                                            data=pkt)) 

+

+        for of_port in config["port_map"].keys():

+            verify_packet(self, pkt, of_port)

+

+        verify_no_other_packets(self)

+

+        #packet out flood, tag packet, because it can't identify vlan has which port

+        #so we do as all action.

+        self.controller.message_send(ofp.message.packet_out(in_port=ofp.OFPP_CONTROLLER,

+                                                            buffer_id=ofp.OFP_NO_BUFFER,

+                                                            actions=[ofp.action.output(

+                                                                     port=ofp.OFPP_FLOOD)],

+                                                            data=vlan_pkt)) 

+

+        for of_port in config["port_map"].keys():

+            verify_packet(self, vlan_pkt, of_port)

+

+        verify_no_other_packets(self)

+

+        #packet out all

+        self.controller.message_send(ofp.message.packet_out(in_port=ofp.OFPP_CONTROLLER,

+                                                            buffer_id=ofp.OFP_NO_BUFFER,

+                                                            actions=[ofp.action.output(

+                                                                     port=ofp.OFPP_FLOOD)],

+                                                            data=pkt)) 

+

+        for of_port in config["port_map"].keys():

+            verify_packet(self, pkt, of_port)

+

+        verify_no_other_packets(self)        

+        

+        #packet out to in port

+        in_port = config["port_map"].keys()[0]

+        self.controller.message_send(ofp.message.packet_out(in_port=in_port,

+                                                            buffer_id=ofp.OFP_NO_BUFFER,

+                                                            actions=[ofp.action.output(

+                                                                     port=in_port)],

+                                                            data=pkt)) 

+

+        verify_packet(self, pkt, in_port)

+        verify_no_other_packets(self)

+

+class L3UcastRoute(base_tests.SimpleDataPlane):

+    """

+    Port1(vlan1, 0x00, 0x00, 0x00, 0x22, 0x22, 0x01, 192.168.1.1) , 

+    Port2(vlan2, 0x00, 0x00, 0x00, 0x22, 0x22, 0x02, 19.168.2.1)

+    """

+    def runTest(self):          

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        if len(config["port_map"]) <2:

+            logging.info("Port count less than 2, can't run this case")

+            return

+        

+        vlan_id=1

+        intf_src_mac=[0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc]

+        dst_mac=[0x00, 0x00, 0x00, 0x22, 0x22, 0x00]

+        dip=0xc0a80001

+        for port in config["port_map"].keys():

+            #add l2 interface group

+            add_one_l2_interface_group(self.controller, port, vlan_id=vlan_id, is_tagged=False, send_barrier=False)

+            dst_mac[5]=vlan_id

+            l3_msg=add_l3_unicast_group(self.controller, port, vlanid=vlan_id, id=vlan_id, src_mac=intf_src_mac, dst_mac=dst_mac)

+            #add vlan flow table

+            add_one_vlan_table_flow(self.controller, port, vlan_id, flag=VLAN_TABLE_FLAG_ONLY_BOTH)

+            #add termination flow

+            add_termination_flow(self.controller, port, 0x0800, intf_src_mac, vlan_id)           

+            #add unicast routing flow

+            dst_ip = dip + (vlan_id<<8)           

+            add_unicast_routing_flow(self.controller, 0x0800, dst_ip, 0, l3_msg.group_id)            

+            vlan_id += 1

+        

+        do_barrier(self.controller)  

+        

+        port1=config["port_map"].keys()[0]

+        port2=config["port_map"].keys()[1]

+        #port 1 to port 2        

+        switch_mac = ':'.join(['%02X' % x for x in intf_src_mac])

+        dst_mac[5]=1

+        port1_mac=':'.join(['%02X' % x for x in dst_mac])

+

+        parsed_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=switch_mac,

+                                       eth_src=port1_mac,

+                                       ip_ttl=64,

+                                       ip_src="192.168.1.1",

+                                       ip_dst='192.168.2.1')

+        pkt=str(parsed_pkt)

+        self.dataplane.send(port1, pkt)

+        #build expect packet

+        dst_mac[5]=2

+        port2_mac=':'.join(['%02X' % x for x in dst_mac])  

+        exp_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=port2_mac,

+                                       eth_src=switch_mac,

+                                       ip_ttl=63,

+                                       ip_src="192.168.1.1",

+                                       ip_dst='192.168.2.1')        

+        pkt=str(exp_pkt)

+        verify_packet(self, pkt, port2)

+        verify_no_other_packets(self)

+

+        #port 2 to port 1

+        switch_mac = ':'.join(['%02X' % x for x in intf_src_mac])

+        dst_mac[5]=2

+        port2_mac=':'.join(['%02X' % x for x in dst_mac])  

+

+        parsed_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=switch_mac,

+                                       eth_src=port2_mac,

+                                       ip_ttl=64,

+                                       ip_src="192.168.2.1",

+                                       ip_dst='192.168.1.1')

+        pkt=str(parsed_pkt)                                       

+        self.dataplane.send(port2, pkt)

+        #build expect packet

+        dst_mac[5]=1

+        port1_mac=':'.join(['%02X' % x for x in dst_mac])  

+        exp_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=port1_mac,

+                                       eth_src=switch_mac,

+                                       ip_ttl=63,

+                                       ip_src="192.168.2.1",

+                                       ip_dst='192.168.1.1')        

+        pkt=str(exp_pkt) 

+        verify_packet(self, pkt, port1)

+        verify_no_other_packets(self)    

+

+class L3UcastRouteOnSamVLANSamPort(base_tests.SimpleDataPlane):

+    """

+    Port1(vlan1, 0x00, 0x00, 0x00, 0x22, 0x22, 0x01, 192.168.1.1) , 

+    Port1(vlan1, 0x00, 0x00, 0x00, 0x22, 0x22, 0x02, 19.168.2.1)

+    """	

+    def runTest(self):          

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+        port = config["port_map"].keys()[0]

+		

+        vlan_id=1

+        intf_src_mac=[0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc]

+        port_mac1=[0x00, 0x00, 0x00, 0x22, 0x22, 0x01]

+        port_mac2=[0x00, 0x00, 0x00, 0x22, 0x22, 0x02]

+        port_ip1=0xc0a80101        

+        port_ip1_str=convertIP4toStr(port_ip1)

+        port_ip2=0xc0a80201

+        port_ip2_str=convertIP4toStr(port_ip2)

+		#add l2 interface group

+        add_one_l2_interface_group(self.controller, port, vlan_id=vlan_id, is_tagged=False, send_barrier=False)

+		#add vlan flow table

+        add_one_vlan_table_flow(self.controller, port, vlan_id, flag=VLAN_TABLE_FLAG_ONLY_BOTH)

+		#add termination flow

+        add_termination_flow(self.controller, port, 0x0800, intf_src_mac, vlan_id)           

+

+        """192.168.1.1->192.168.2.1"""

+        l3_msg=add_l3_unicast_group(self.controller, port, vlanid=vlan_id, id=1, src_mac=intf_src_mac, dst_mac=port_mac2)

+        add_unicast_routing_flow(self.controller, 0x0800, port_ip2, 0, l3_msg.group_id)            

+        """192.168.1.1->192.168.2.1"""

+        l3_msg=add_l3_unicast_group(self.controller, port, vlanid=vlan_id, id=2, src_mac=intf_src_mac, dst_mac=port_mac1)

+        add_unicast_routing_flow(self.controller, 0x0800, port_ip1, 0, l3_msg.group_id)            

+ 

+        do_barrier(self.controller)  

+		

+        """send packet to verify"""

+        """192.168.1.1->192.168.2.1"""        

+        switch_mac_str = convertMACtoStr(intf_src_mac)

+        port_mac1_str  = convertMACtoStr(port_mac1)

+        port_mac2_str  = convertMACtoStr(port_mac2)

+        ttl=64

+		#send packet

+        parsed_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=switch_mac_str,

+                                       eth_src=port_mac1_str,

+                                       ip_ttl=ttl,

+                                       ip_src=port_ip1_str,

+                                       ip_dst=port_ip2_str)

+        pkt=str(parsed_pkt)

+        self.dataplane.send(port, pkt)

+        #build expect packet

+        exp_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=port_mac2_str,

+                                       eth_src=switch_mac_str,

+                                       ip_ttl=(ttl-1),

+                                       ip_src=port_ip1_str,

+                                       ip_dst=port_ip2_str)

+        pkt=str(exp_pkt)

+        verify_packet(self, pkt, port)

+        verify_no_other_packets(self)

+

+        """192.168.2.1->192.168.1.1"""

+        parsed_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=switch_mac_str,

+                                       eth_src=port_mac2_str,

+                                       ip_ttl=ttl,

+                                       ip_src=port_ip2_str,

+                                       ip_dst=port_ip1_str)

+        pkt=str(parsed_pkt)                                       

+        self.dataplane.send(port, pkt)

+        #build expect packet

+        exp_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=port_mac1_str,

+                                       eth_src=switch_mac_str,

+                                       ip_ttl=(ttl-1),

+                                       ip_src=port_ip2_str,

+                                       ip_dst=port_ip1_str)        

+        pkt=str(exp_pkt) 

+        verify_packet(self, pkt, port)

+        verify_no_other_packets(self)    

+

+class L3UcastRouteOnDiffVLANSamPort(base_tests.SimpleDataPlane):

+    """

+    Port1(vlan1, 0x00, 0x00, 0x00, 0x22, 0x22, 0x01, 192.168.1.1) , 

+    Port1(vlan2, 0x00, 0x00, 0x00, 0x22, 0x22, 0x02, 19.168.2.1)

+    """	

+    def runTest(self):          

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+        port = config["port_map"].keys()[0]

+		

+        port_vlan_id1=1

+        port_vlan_id2=2

+        intf_src_mac=[0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc]

+        port_mac1=[0x00, 0x00, 0x00, 0x22, 0x22, 0x01]

+        port_mac2=[0x00, 0x00, 0x00, 0x22, 0x22, 0x02]

+        port_ip1=0xc0a80101

+        port_ip1_str=convertIP4toStr(port_ip1)

+        port_ip2=0xc0a80201

+        port_ip2_str=convertIP4toStr(port_ip2)

+		#add l2 interface group

+        add_one_l2_interface_group(self.controller, port, vlan_id=port_vlan_id1, is_tagged=True, send_barrier=False)

+        add_one_l2_interface_group(self.controller, port, vlan_id=port_vlan_id2, is_tagged=True, send_barrier=False)

+		#add vlan flow table

+        add_one_vlan_table_flow(self.controller, port, port_vlan_id1, flag=VLAN_TABLE_FLAG_ONLY_BOTH)

+        add_one_vlan_table_flow(self.controller, port, port_vlan_id2, flag=VLAN_TABLE_FLAG_ONLY_BOTH)		

+		#add termination flow

+        add_termination_flow(self.controller, port, 0x0800, intf_src_mac, port_vlan_id1)           

+        add_termination_flow(self.controller, port, 0x0800, intf_src_mac, port_vlan_id2)           

+		

+        """192.168.1.1->192.168.2.1"""

+        l3_msg=add_l3_unicast_group(self.controller, port, vlanid=port_vlan_id2, id=1, src_mac=intf_src_mac, dst_mac=port_mac2)

+        add_unicast_routing_flow(self.controller, 0x0800, port_ip2, 0, l3_msg.group_id)            

+        """192.168.1.1->192.168.2.1"""

+        l3_msg=add_l3_unicast_group(self.controller, port, vlanid=port_vlan_id1, id=2, src_mac=intf_src_mac, dst_mac=port_mac1)

+        add_unicast_routing_flow(self.controller, 0x0800, port_ip1, 0, l3_msg.group_id)            

+ 

+        do_barrier(self.controller)  

+		

+        """send packet to verify"""  

+        """192.168.1.1->192.168.2.1"""        

+        switch_mac_str =convertMACtoStr(intf_src_mac)

+        port_mac1_str= convertMACtoStr(port_mac1)

+        port_mac2_str= convertMACtoStr(port_mac2)

+        ttl=64

+		#send packet

+        parsed_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=switch_mac_str,

+                                       eth_src=port_mac1_str,

+									   dl_vlan_enable=True,

+									   vlan_vid=port_vlan_id1,									   

+                                       ip_ttl=ttl,

+                                       ip_src=port_ip1_str,

+                                       ip_dst=port_ip2_str)

+        pkt=str(parsed_pkt)

+        self.dataplane.send(port, pkt)

+        #build expect packet

+        exp_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=port_mac2_str,

+                                       eth_src=switch_mac_str,

+									   dl_vlan_enable=True,

+									   vlan_vid=port_vlan_id2,									   

+                                       ip_ttl=(ttl-1),

+                                       ip_src=port_ip1_str,

+                                       ip_dst=port_ip2_str)

+        pkt=str(exp_pkt)

+        verify_packet(self, pkt, port)

+        verify_no_other_packets(self)

+

+        """192.168.2.1->192.168.1.1"""

+        switch_mac = convertMACtoStr(intf_src_mac)

+        port_mac2_str=convertMACtoStr(port_mac2)

+

+        parsed_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=switch_mac_str,

+                                       eth_src=port_mac2_str,

+									   dl_vlan_enable=True,

+									   vlan_vid=port_vlan_id2,									   

+                                       ip_ttl=ttl,

+                                       ip_src=port_ip2_str,

+                                       ip_dst=port_ip1_str)

+        pkt=str(parsed_pkt)                                       

+        self.dataplane.send(port, pkt)

+        #build expect packet

+        exp_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=port_mac1_str,

+                                       eth_src=switch_mac_str,

+									   dl_vlan_enable=True,

+									   vlan_vid=port_vlan_id1,

+                                       ip_ttl=(ttl-1),

+                                       ip_src=port_ip2_str,

+                                       ip_dst=port_ip1_str)        

+        pkt=str(exp_pkt) 

+        verify_packet(self, pkt, port)

+        verify_no_other_packets(self)    

+		

+class L3UcastVrfRouteOnSamVLANSamPort(base_tests.SimpleDataPlane):

+    """

+    Port1(vlan1, VRF1, 0x00, 0x00, 0x00, 0x22, 0x22, 0x01, 192.168.1.1) , 

+    Port1(vlan1, VRF1, 0x00, 0x00, 0x00, 0x22, 0x22, 0x02, 19.168.2.1)

+    Port1(vlan2, VRF2, 0x00, 0x00, 0x00, 0x22, 0x22, 0x01, 192.168.1.1) , 

+    Port1(vlan2, VRF2, 0x00, 0x00, 0x00, 0x22, 0x22, 0x02, 19.168.2.1)

+    

+    """	

+    def runTest(self):          

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+        port = config["port_map"].keys()[0]

+		

+        vrf1=1

+        vrf2=2

+        vrf1_vlan_id=1

+        vrf2_vlan_id=2

+        intf_src_mac=[0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc]

+        port_mac1=[0x00, 0x00, 0x00, 0x22, 0x22, 0x01]

+        port_mac2=[0x00, 0x00, 0x00, 0x22, 0x22, 0x02]

+        port_ip1=0xc0a80101        

+        port_ip1_str=convertIP4toStr(port_ip1)

+        port_ip2=0xc0a80201

+        port_ip2_str=convertIP4toStr(port_ip2)

+		#add l2 interface group

+        add_one_l2_interface_group(self.controller, port, vlan_id=vrf1_vlan_id, is_tagged=True, send_barrier=False)

+        add_one_l2_interface_group(self.controller, port, vlan_id=vrf2_vlan_id, is_tagged=True, send_barrier=False)

+		#add vlan flow table

+        add_one_vlan_table_flow(self.controller, port, vrf1_vlan_id, vrf=vrf1, flag=VLAN_TABLE_FLAG_ONLY_TAG)

+        add_one_vlan_table_flow(self.controller, port, vrf2_vlan_id, vrf=vrf2, flag=VLAN_TABLE_FLAG_ONLY_TAG)

+        

+		#add termination flow

+        add_termination_flow(self.controller, 0, 0x0800, intf_src_mac, vrf1_vlan_id)

+        add_termination_flow(self.controller, 0, 0x0800, intf_src_mac, vrf2_vlan_id)

+        

+        """192.168.1.1->192.168.2.1"""

+        l3_msg=add_l3_unicast_group(self.controller, port, vlanid=vrf1_vlan_id, id=1, src_mac=intf_src_mac, dst_mac=port_mac2)

+        add_unicast_routing_flow(self.controller, 0x0800, port_ip2, 0, l3_msg.group_id, vrf1)

+        l3_msg=add_l3_unicast_group(self.controller, port, vlanid=vrf2_vlan_id, id=2, src_mac=intf_src_mac, dst_mac=port_mac2)

+        add_unicast_routing_flow(self.controller, 0x0800, port_ip2, 0, l3_msg.group_id, vrf2)

+        

+        """192.168.1.1->192.168.2.1"""

+        l3_msg=add_l3_unicast_group(self.controller, port, vlanid=vrf1_vlan_id, id=3, src_mac=intf_src_mac, dst_mac=port_mac1)

+        add_unicast_routing_flow(self.controller, 0x0800, port_ip1, 0, l3_msg.group_id, vrf1)

+        l3_msg=add_l3_unicast_group(self.controller, port, vlanid=vrf2_vlan_id, id=4, src_mac=intf_src_mac, dst_mac=port_mac1)

+        add_unicast_routing_flow(self.controller, 0x0800, port_ip1, 0, l3_msg.group_id, vrf2)

+        

+        do_barrier(self.controller)  

+	

+        """send packet to verify on VRF vrf1"""

+        """192.168.1.1->192.168.2.1"""        

+        switch_mac_str = convertMACtoStr(intf_src_mac)

+        port_mac1_str  = convertMACtoStr(port_mac1)

+        port_mac2_str  = convertMACtoStr(port_mac2)

+        ttl=64

+		#send packet

+        parsed_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=switch_mac_str,

+                                       eth_src=port_mac1_str,

+                                       dl_vlan_enable=True,

+                                       vlan_vid=vrf1_vlan_id,

+                                       ip_ttl=ttl,

+                                       ip_src=port_ip1_str,

+                                       ip_dst=port_ip2_str)

+        pkt=str(parsed_pkt)

+        self.dataplane.send(port, pkt)

+        #build expect packet

+        exp_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=port_mac2_str,

+                                       eth_src=switch_mac_str,

+                                       dl_vlan_enable=True,

+                                       vlan_vid=vrf1_vlan_id,                                       

+                                       ip_ttl=(ttl-1),

+                                       ip_src=port_ip1_str,

+                                       ip_dst=port_ip2_str)

+        pkt=str(exp_pkt)

+        verify_packet(self, pkt, port)

+        verify_no_other_packets(self)

+

+        """192.168.2.1->192.168.1.1"""

+        parsed_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=switch_mac_str,

+                                       eth_src=port_mac2_str,

+                                       dl_vlan_enable=True,

+                                       vlan_vid=vrf1_vlan_id,                                       

+                                       ip_ttl=ttl,

+                                       ip_src=port_ip2_str,

+                                       ip_dst=port_ip1_str)

+        pkt=str(parsed_pkt)                                       

+        self.dataplane.send(port, pkt)

+        #build expect packet

+        exp_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=port_mac1_str,

+                                       eth_src=switch_mac_str,

+                                       dl_vlan_enable=True,

+                                       vlan_vid=vrf1_vlan_id,                                       

+                                       ip_ttl=(ttl-1),

+                                       ip_src=port_ip2_str,

+                                       ip_dst=port_ip1_str)        

+        pkt=str(exp_pkt) 

+        verify_packet(self, pkt, port)

+        verify_no_other_packets(self)    

+       

+		

+        """send packet to verify on VRF vrf2"""

+        """192.168.1.1->192.168.2.1"""        

+        switch_mac_str = convertMACtoStr(intf_src_mac)

+        port_mac1_str  = convertMACtoStr(port_mac1)

+        port_mac2_str  = convertMACtoStr(port_mac2)

+        ttl=64

+		#send packet

+        parsed_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=switch_mac_str,

+                                       eth_src=port_mac1_str,

+                                       dl_vlan_enable=True,

+                                       vlan_vid=vrf2_vlan_id,

+                                       ip_ttl=ttl,

+                                       ip_src=port_ip1_str,

+                                       ip_dst=port_ip2_str)

+        pkt=str(parsed_pkt)

+        self.dataplane.send(port, pkt)

+        #build expect packet

+        exp_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=port_mac2_str,

+                                       eth_src=switch_mac_str,

+                                       dl_vlan_enable=True,

+                                       vlan_vid=vrf2_vlan_id,                                       

+                                       ip_ttl=(ttl-1),

+                                       ip_src=port_ip1_str,

+                                       ip_dst=port_ip2_str)

+        pkt=str(exp_pkt)

+        verify_packet(self, pkt, port)

+        verify_no_other_packets(self)

+

+        """192.168.2.1->192.168.1.1"""

+        parsed_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=switch_mac_str,

+                                       eth_src=port_mac2_str,

+                                       dl_vlan_enable=True,

+                                       vlan_vid=vrf2_vlan_id,                                       

+                                       ip_ttl=ttl,

+                                       ip_src=port_ip2_str,

+                                       ip_dst=port_ip1_str)

+        pkt=str(parsed_pkt)                                       

+        self.dataplane.send(port, pkt)

+        #build expect packet

+        exp_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=port_mac1_str,

+                                       eth_src=switch_mac_str,

+                                       dl_vlan_enable=True,

+                                       vlan_vid=vrf2_vlan_id,                                       

+                                       ip_ttl=(ttl-1),

+                                       ip_src=port_ip2_str,

+                                       ip_dst=port_ip1_str)        

+        pkt=str(exp_pkt) 

+        verify_packet(self, pkt, port)

+        verify_no_other_packets(self)          

+        

+        

+		  

+                

+class L3UcastECMP(base_tests.SimpleDataPlane):

+    """

+    Port1(vlan1, 0x00, 0x00, 0x00, 0x22, 0x22, 0x01, 192.168.1.1) , 

+    Port2(vlan2, 0x00, 0x00, 0x00, 0x22, 0x22, 0x02, 19.168.2.1)

+    """

+    def runTest(self):          

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        if len(config["port_map"]) <2:

+            logging.info("Port count less than 2, can't run this case")

+            return

+        

+        vlan_id=1

+        intf_src_mac=[0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc]

+        dst_mac=[0x00, 0x00, 0x00, 0x22, 0x22, 0x00]

+        dip=0xc0a80001

+        for port in config["port_map"].keys():

+            #add l2 interface group

+            add_one_l2_interface_group(self.controller, port, vlan_id=vlan_id, is_tagged=False, send_barrier=False)

+            dst_mac[5]=vlan_id

+            l3_msg=add_l3_unicast_group(self.controller, port, vlanid=vlan_id, id=vlan_id, src_mac=intf_src_mac, dst_mac=dst_mac)            

+            ecmp_msg=add_l3_ecmp_group(self.controller, vlan_id, [l3_msg.group_id])

+            #add vlan flow table

+            add_one_vlan_table_flow(self.controller, port, vlan_id, flag=VLAN_TABLE_FLAG_ONLY_BOTH)

+            #add termination flow

+            add_termination_flow(self.controller, port, 0x0800, intf_src_mac, vlan_id)           

+            #add unicast routing flow

+            dst_ip = dip + (vlan_id<<8)

+            #ECMP shall have prefix not 32

+            add_unicast_routing_flow(self.controller, 0x0800, dst_ip, 0xffffff00, ecmp_msg.group_id)            

+            vlan_id += 1

+        

+        do_barrier(self.controller)  

+        

+        port1=config["port_map"].keys()[0]

+        port2=config["port_map"].keys()[1]

+        #port 1 to port 2        

+        switch_mac = ':'.join(['%02X' % x for x in intf_src_mac])

+        dst_mac[5]=1

+        port1_mac=':'.join(['%02X' % x for x in dst_mac])

+

+        parsed_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=switch_mac,

+                                       eth_src=port1_mac,

+                                       ip_ttl=64,

+                                       ip_src="192.168.1.1",

+                                       ip_dst='192.168.2.1')

+        pkt=str(parsed_pkt)

+        self.dataplane.send(port1, pkt)

+        #build expect packet

+        dst_mac[5]=2

+        port2_mac=':'.join(['%02X' % x for x in dst_mac])  

+        exp_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=port2_mac,

+                                       eth_src=switch_mac,

+                                       ip_ttl=63,

+                                       ip_src="192.168.1.1",

+                                       ip_dst='192.168.2.1')        

+        pkt=str(exp_pkt)

+        verify_packet(self, pkt, port2)

+        verify_no_other_packets(self)

+

+        #port 2 to port 1

+        switch_mac = ':'.join(['%02X' % x for x in intf_src_mac])

+        dst_mac[5]=2

+        port2_mac=':'.join(['%02X' % x for x in dst_mac])  

+

+        parsed_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=switch_mac,

+                                       eth_src=port2_mac,

+                                       ip_ttl=64,

+                                       ip_src="192.168.2.1",

+                                       ip_dst='192.168.1.1')

+        pkt=str(parsed_pkt)                                       

+        self.dataplane.send(port2, pkt)

+        #build expect packet

+        dst_mac[5]=1

+        port1_mac=':'.join(['%02X' % x for x in dst_mac])  

+        exp_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=port1_mac,

+                                       eth_src=switch_mac,

+                                       ip_ttl=63,

+                                       ip_src="192.168.2.1",

+                                       ip_dst='192.168.1.1')        

+        pkt=str(exp_pkt) 

+        verify_packet(self, pkt, port1)

+        verify_no_other_packets(self)    

+

+                

+class L3UcastECMP2(base_tests.SimpleDataPlane):

+    """

+    Port1(vlan1, 0x00, 0x00, 0x00, 0x22, 0x22, 0x01, 192.168.1.1) , 

+    Port2(vlan2, 0x00, 0x00, 0x00, 0x22, 0x22, 0x02, 19.168.2.1)

+    Portn(vlann, 0x00, 0x00, 0x00, 0x22, 0x22, 0x0n, 19.168.n.1)    

+    """

+    

+    def runTest(self):          

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        if len(config["port_map"]) <3:

+            logging.info("Port count less than 3, can't run this case")

+            return

+        

+        vlan_id=1

+        intf_src_mac=[0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc]

+        same_dst_mac=[0x00, 0x00, 0x00, 0x22, 0x22, 0x22]

+

+        l3_ucast_gips=[]        

+        tx_port = config["port_map"].keys()[0]        

+        for port in config["port_map"].keys():

+            #add l2 interface group

+            add_one_l2_interface_group(self.controller, port, vlan_id=vlan_id, is_tagged=False, send_barrier=False)

+            if tx_port != port:            

+                l3_msg=add_l3_unicast_group(self.controller, port, vlanid=vlan_id, id=vlan_id, src_mac=intf_src_mac, dst_mac=same_dst_mac)            

+                l3_ucast_gips.append(l3_msg.group_id)

+            #add vlan flow table

+            add_one_vlan_table_flow(self.controller, port, vlan_id, flag=VLAN_TABLE_FLAG_ONLY_BOTH)

+            #add termination flow

+            add_termination_flow(self.controller, port, 0x0800, intf_src_mac, vlan_id)           

+            vlan_id += 1

+

+        tx_dip=0x0a0a0a0a

+        tx_sip=0x0b0a0a0a             

+        ecmp_msg=add_l3_ecmp_group(self.controller, vlan_id, l3_ucast_gips)            

+        #ECMP shall have prefix not 32

+        add_unicast_routing_flow(self.controller, 0x0800, tx_dip, 0xffffff00, ecmp_msg.group_id)            

+

+        do_barrier(self.controller)          

+

+        switch_mac = ':'.join(['%02X' % x for x in intf_src_mac])

+        packet_src_mac="00:00:33:44:55:66"

+        #from unknown src ip to unknown dst ip, to verify ecmp

+        parsed_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=switch_mac,

+                                       eth_src=packet_src_mac,

+                                       ip_ttl=64,

+                                       ip_src=convertIP4toStr(tx_sip),

+                                       ip_dst=convertIP4toStr(tx_dip))

+        self.dataplane.send(tx_port, str(parsed_pkt))

+        #build expect packet

+        dst_mac=':'.join(['%02X' % x for x in same_dst_mac])

+        exp_pkt = simple_tcp_packet(pktlen=100, 

+                                   eth_dst=dst_mac,

+                                   eth_src=switch_mac,

+                                   ip_ttl=63,

+                                   ip_src=convertIP4toStr(tx_sip),

+                                   ip_dst=convertIP4toStr(tx_dip)) 

+                                       

+        verify_packet(self, exp_pkt, config["port_map"].keys()[2])

+        verify_no_other_packets(self)

+        tx_sip=tx_sip+0x01000000  

+        #from unknown scr ip to unknown dst ip, to verify ecmp

+        parsed_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst=switch_mac,

+                                       eth_src=packet_src_mac,

+                                       ip_ttl=64,

+                                       ip_src=convertIP4toStr(tx_sip),

+                                       ip_dst=convertIP4toStr(tx_dip))

+        self.dataplane.send(tx_port, str(parsed_pkt))

+        #build expect packet

+        dst_mac=':'.join(['%02X' % x for x in same_dst_mac])

+        exp_pkt = simple_tcp_packet(pktlen=100, 

+                                   eth_dst=dst_mac,

+                                   eth_src=switch_mac,

+                                   ip_ttl=63,

+                                   ip_src=convertIP4toStr(tx_sip),

+                                   ip_dst=convertIP4toStr(tx_dip)) 

+                                       

+        verify_packet(self, exp_pkt, config["port_map"].keys()[1])

+        verify_no_other_packets(self)

+

+class L3McastRoute1(base_tests.SimpleDataPlane):

+    """

+    Mcast routing, From VLAN 1 to VLAN 2

+    """

+    def runTest(self):          

+        """

+        port1 (vlan 1)-> port 2 (vlan 2)

+        """

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        if len(config["port_map"]) <3:

+            logging.info("Port count less than 2, can't run this case")

+            return

+

+        vlan_id =1

+        port2_out_vlan=2

+        port3_out_vlan=3

+        in_vlan=1 #macast group vid shall use input vlan diffe from l3 interface use output vlan        

+        intf_src_mac=[0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc]

+        intf_src_mac_str=':'.join(['%02X' % x for x in intf_src_mac])        

+        dst_mac=[0x01, 0x00, 0x5e, 0x01, 0x01, 0x01]

+        dst_mac_str=':'.join(['%02X' % x for x in dst_mac])

+        port1_mac=[0x00, 0x11, 0x11, 0x11, 0x11, 0x11]

+        port1_mac_str=':'.join(['%02X' % x for x in port1_mac])

+        src_ip=0xc0a80101

+        src_ip_str="192.168.1.1"

+        dst_ip=0xe0010101

+        dst_ip_str="224.1.1.1"

+        

+        port1=config["port_map"].keys()[0]

+        port2=config["port_map"].keys()[1]

+        port3=config["port_map"].keys()[2]

+

+        #add l2 interface group

+        for port in config["port_map"].keys():        

+            add_one_l2_interface_group(self.controller, port, vlan_id=vlan_id, is_tagged=False, send_barrier=False)

+            #add vlan flow table

+            add_one_vlan_table_flow(self.controller, port, vlan_id, flag=VLAN_TABLE_FLAG_ONLY_BOTH)            

+            vlan_id +=1            

+

+        #add termination flow

+        add_termination_flow(self.controller, port1, 0x0800, [0x01, 0x00, 0x5e, 0x00, 0x00, 0x00], vlan_id)

+

+        #add l3 interface group

+        port2_ucast_msg=add_l3_interface_group(self.controller, port2, port2_out_vlan, 2, intf_src_mac)

+        port3_ucast_msg=add_l3_interface_group(self.controller, port3, port3_out_vlan, 3, intf_src_mac)        

+        mcat_group_msg=add_l3_mcast_group(self.controller, in_vlan,  2, [port2_ucast_msg.group_id, port3_ucast_msg.group_id])

+        add_mcast4_routing_flow(self.controller, in_vlan, src_ip, 0, dst_ip, mcat_group_msg.group_id)               

+        

+        parsed_pkt = simple_udp_packet(pktlen=100, 

+                                       eth_dst=dst_mac_str,

+                                       eth_src=port1_mac_str,

+                                       ip_ttl=64,

+                                       ip_src=src_ip_str,

+                                       ip_dst=dst_ip_str)

+        pkt=str(parsed_pkt)

+        self.dataplane.send(port1, pkt)            

+        parsed_pkt = simple_udp_packet(pktlen=100, 

+                                       eth_dst=dst_mac_str,

+                                       eth_src=intf_src_mac_str,

+                                       ip_ttl=63,

+                                       ip_src=src_ip_str,

+                                       ip_dst=dst_ip_str)

+        pkt=str(parsed_pkt)            

+        verify_packet(self, pkt, port2)

+        verify_packet(self, pkt, port3)        

+        verify_no_other_packets(self)               

+

+class L3McastRoute2(base_tests.SimpleDataPlane):

+    """

+    Mcast routing, but on same vlan (l2mcast)

+    """

+    def runTest(self):          

+        """

+        port1 (vlan 1)-> port 2 (vlan 1)

+        """

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+        

+        if len(config["port_map"]) <2:

+            logging.info("Port count less than 2, can't run this case")

+            return

+

+        vlan_id =1

+        intf_src_mac=[0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc]

+        intf_src_mac_str=':'.join(['%02X' % x for x in intf_src_mac])        

+        dst_mac=[0x01, 0x00, 0x5e, 0x01, 0x01, 0x01]

+        dst_mac_str=':'.join(['%02X' % x for x in dst_mac])

+        port1_mac=[0x00, 0x11, 0x11, 0x11, 0x11, 0x11]

+        port1_mac_str=':'.join(['%02X' % x for x in port1_mac])

+        src_ip=0xc0a80101

+        src_ip_str="192.168.1.1"

+        dst_ip=0xe0010101

+        dst_ip_str="224.1.1.1"

+        

+        port1=config["port_map"].keys()[0]

+        port2=config["port_map"].keys()[1]

+

+        

+        #add l2 interface group

+        l2_intf_group_list=[]

+        for port in config["port_map"].keys():

+            if port != port1 and port !=port2:

+                continue

+            l2_intf_gid, msg=add_one_l2_interface_group(self.controller, port, vlan_id=vlan_id, is_tagged=False, send_barrier=False)

+            l2_intf_group_list.append(l2_intf_gid)

+            #add vlan flow table

+            add_one_vlan_table_flow(self.controller, port, vlan_id, flag=VLAN_TABLE_FLAG_ONLY_BOTH)            

+

+        #add termination flow

+        add_termination_flow(self.controller, port1, 0x0800, [0x01, 0x00, 0x5e, 0x00, 0x00, 0x00], vlan_id)

+

+        #add l3 interface group

+        mcat_group_msg=add_l3_mcast_group(self.controller, vlan_id,  2, l2_intf_group_list)

+        add_mcast4_routing_flow(self.controller, vlan_id, src_ip, 0, dst_ip, mcat_group_msg.group_id)               

+

+        parsed_pkt = simple_udp_packet(pktlen=100, 

+                                       eth_dst=dst_mac_str,

+                                       eth_src=port1_mac_str,

+                                       ip_ttl=64,

+                                       ip_src=src_ip_str,

+                                       ip_dst=dst_ip_str)

+        pkt=str(parsed_pkt)

+        self.dataplane.send(port1, pkt)            

+        verify_packet(self, pkt, port2)

+        verify_no_other_packets(self)               

+            

+

+            

diff --git a/Fabric/Utilities/accton/flow_test2.py b/Fabric/Utilities/accton/flow_test2.py
new file mode 100755
index 0000000..cfe1296
--- /dev/null
+++ b/Fabric/Utilities/accton/flow_test2.py
@@ -0,0 +1,74 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+"""

+Flow Test

+

+Test each flow table can set entry, and packet rx correctly.

+"""

+

+import logging

+

+from oftest import config

+import oftest.base_tests as base_tests

+import ofp

+from oftest.testutils import *

+from accton_util import *

+

+class qinq(base_tests.SimpleDataPlane):

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)   

+        

+        in_port = config["port_map"].keys()[0]

+        out_port=config["port_map"].keys()[1]        

+        out_vlan=10

+        add_vlan_table_flow_pvid(self.controller, in_port, None, out_vlan, False)

+        add_vlan_table_flow_pvid(self.controller, in_port, 1,out_vlan, False)        

+        group_id, msg=add_one_l2_interface_group(self.controller, out_port, out_vlan,  True, False)

+        #add acl 

+        match = ofp.match()

+        match.oxm_list.append(ofp.oxm.in_port(in_port))    

+        request = ofp.message.flow_add(

+                table_id=60,

+                cookie=42,

+                match=match,

+                instructions=[

+                    ofp.instruction.write_actions(

+                        actions=[

+                            ofp.action.group(msg.group_id)])

+                    ],

+                buffer_id=ofp.OFP_NO_BUFFER,

+                priority=1000) 

+        self.controller.message_send(request)  

+     

+        #input untag packet

+

+        parsed_pkt = simple_tcp_packet(pktlen=100)

+        pkt = str(parsed_pkt)

+        self.dataplane.send(in_port, pkt)

+    

+        parsed_pkt = simple_tcp_packet(pktlen=104, dl_vlan_enable=True, vlan_vid=10)

+        verify_packet(self, str(parsed_pkt), out_port)

+

+        #input tag packet

+        parsed_pkt = simple_tcp_packet(pktlen=104, dl_vlan_enable=True, vlan_vid=1)

+        pkt = str(parsed_pkt)

+        self.dataplane.send(in_port, pkt)

+    

+        parsed_pkt = simple_tcp_packet_two_vlan(pktlen=108, out_dl_vlan_enable=True, out_vlan_vid=10,

+                                                in_dl_vlan_enable=True, in_vlan_vid=1)

+        verify_packet(self, str(parsed_pkt), out_port)

diff --git a/Fabric/Utilities/accton/group_test.py b/Fabric/Utilities/accton/group_test.py
new file mode 100755
index 0000000..67d6fda
--- /dev/null
+++ b/Fabric/Utilities/accton/group_test.py
@@ -0,0 +1,883 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+"""

+Group table test

+Verify each group table can created correctly

+"""

+from oftest import config

+

+import logging

+import random

+

+from oftest import config

+import oftest

+import oftest.base_tests as base_tests

+import ofp

+

+from oftest.testutils import *

+from accton_util import *

+

+def getkey(type):

+    def byGroupId(stats_entry):

+        return stats_entry.group_id

+        

+    def byGroupType(stats_entry):

+        return stats_entry.group_type

+

+        

+    if type == "group_id":

+        return byGroupId

+    elif type == "group_type":

+        return byGroupType

+    else:

+         assert(0)

+    return byGroupId        

+               

+class L2InterfaceGroupOne(base_tests.SimpleDataPlane):

+    def runTest(self):    

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)    

+

+        group_list1, msg1 = add_one_l2_interface_group(self.controller, config["port_map"].keys()[0], 1,  False, False)

+        stats = get_stats(self, ofp.message.group_desc_stats_request())

+ 

+        verify_group_stats=[ofp.group_desc_stats_entry(

+                          group_type=msg1.group_type,

+                          group_id=msg1.group_id,

+                          buckets=msg1.buckets)]

+

+        self.maxDiff=None

+

+        self.assertEquals(stats, verify_group_stats)

+

+class L2InterfaceGroup(base_tests.SimpleDataPlane):

+    def runTest(self):    

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)    

+

+        group_list1, msg1 = add_l2_interface_grouop(self.controller, config["port_map"].keys(), 1,  False, False)

+        group_list2, msg2 =add_l2_interface_grouop(self.controller, config["port_map"].keys(), 2,  False, False)       

+        

+        stats = get_stats(self, ofp.message.group_desc_stats_request())

+ 

+        verify_group_stats=[]

+

+        for msg in msg1:

+            verify_group_stats.append(ofp.group_desc_stats_entry(

+                                      group_type=msg.group_type,

+                                      group_id=msg.group_id,

+                                      buckets=msg.buckets))        

+

+        for msg in msg2:

+            verify_group_stats.append(ofp.group_desc_stats_entry(

+                                      group_type=msg.group_type,

+                                      group_id=msg.group_id,

+                                      buckets=msg.buckets))

+

+        verify_group_stats=sorted(verify_group_stats, key=getkey("group_id")) 

+        stats=sorted(stats, key=getkey("group_id")) 

+        #self.maxDiff=None        

+        self.assertEquals(stats, verify_group_stats)

+        

+class L2McastGroup(base_tests.SimpleDataPlane):

+    def runTest(self):

+        delete_all_flows(self.controller)    

+        delete_all_groups(self.controller)    

+        

+        group_list1, msg1 = add_l2_interface_grouop(self.controller, config["port_map"].keys(), 1,  False, False)       

+        msg2=add_l2_mcast_group(self.controller, config["port_map"].keys(), 1, 1)

+        

+        group_list1, msg3 = add_l2_interface_grouop(self.controller, config["port_map"].keys(), 2,  False, False)               

+        msg4=add_l2_mcast_group(self.controller, config["port_map"].keys(), 2, 2)

+

+        stats = get_stats(self, ofp.message.group_desc_stats_request())

+        

+        verify_group_stats=[]

+        for msg in msg1:

+            verify_group_stats.append(ofp.group_desc_stats_entry(

+                                      group_type=msg.group_type,

+                                      group_id=msg.group_id,

+                                      buckets=msg.buckets)

+                                      )

+        

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=msg2.group_type,

+                                  group_id=msg2.group_id,

+                                  buckets=msg2.buckets)

+                                  )

+        

+        for msg in msg3:

+            verify_group_stats.append(ofp.group_desc_stats_entry(

+                                      group_type=msg.group_type,

+                                      group_id=msg.group_id,

+                                      buckets=msg.buckets)

+                                      )

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=msg4.group_type,

+                                  group_id=msg4.group_id,

+                                  buckets=msg4.buckets)

+                                  )

+                                  

+        verify_group_stats=sorted(verify_group_stats, key=getkey("group_id")) 

+        stats=sorted(stats, key=getkey("group_id"))                                   

+        self.maxDiff=None

+        self.assertEquals(stats, verify_group_stats)

+

+

+class L2FloodGroup(base_tests.SimpleDataPlane):

+    def runTest(self):

+        delete_all_flows(self.controller)    

+        delete_all_groups(self.controller)    

+        

+        group_list1, msg1 = add_l2_interface_grouop(self.controller, config["port_map"].keys(), 1,  False, False)       

+        msg2=add_l2_flood_group(self.controller, config["port_map"].keys(), 1, 1)

+        

+        group_list1, msg3 = add_l2_interface_grouop(self.controller, config["port_map"].keys(), 2,  False, False)               

+        msg4=add_l2_flood_group(self.controller, config["port_map"].keys(), 2, 2)

+

+        stats = get_stats(self, ofp.message.group_desc_stats_request())

+        

+        verify_group_stats=[]

+        for msg in msg1:

+            verify_group_stats.append(ofp.group_desc_stats_entry(

+                                      group_type=msg.group_type,

+                                      group_id=msg.group_id,

+                                      buckets=msg.buckets)

+                                      )

+        

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=msg2.group_type,

+                                  group_id=msg2.group_id,

+                                  buckets=msg2.buckets)

+                                  )

+        

+        for msg in msg3:

+            verify_group_stats.append(ofp.group_desc_stats_entry(

+                                      group_type=msg.group_type,

+                                      group_id=msg.group_id,

+                                      buckets=msg.buckets)

+                                      )

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=msg4.group_type,

+                                  group_id=msg4.group_id,

+                                  buckets=msg4.buckets)

+                                  )

+                                  

+        verify_group_stats=sorted(verify_group_stats, key=getkey("group_id")) 

+        stats=sorted(stats, key=getkey("group_id"))                                   

+        self.maxDiff=None

+        self.assertEquals(stats, verify_group_stats)

+

+

+class L2RewriteGroup(base_tests.SimpleDataPlane):

+    def runTest(self):

+        delete_all_flows(self.controller)    

+        delete_all_groups(self.controller)    

+        

+        group_list1, msg1 = add_l2_interface_grouop(self.controller, config["port_map"].keys(), 1,  False, False)       

+        msg2=add_l2_rewrite_group(self.controller, config["port_map"].keys()[0], 1, 1, [00,11,22,33,44,55], [00,22,22,22,22,22])

+        

+        group_list1, msg3 = add_l2_interface_grouop(self.controller, config["port_map"].keys(), 2,  False, False)               

+        msg4=add_l2_rewrite_group(self.controller, config["port_map"].keys()[0], 2, 2, [00,11,22,33,44,55], [00,33,33,33,33,33])

+

+        stats = get_stats(self, ofp.message.group_desc_stats_request())

+        

+        verify_group_stats=[]

+        for msg in msg1:

+            verify_group_stats.append(ofp.group_desc_stats_entry(

+                                      group_type=msg.group_type,

+                                      group_id=msg.group_id,

+                                      buckets=msg.buckets)

+                                      )

+        

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=msg2.group_type,

+                                  group_id=msg2.group_id,

+                                  buckets=msg2.buckets)

+                                  )

+        

+        for msg in msg3:

+            verify_group_stats.append(ofp.group_desc_stats_entry(

+                                      group_type=msg.group_type,

+                                      group_id=msg.group_id,

+                                      buckets=msg.buckets)

+                                      )

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=msg4.group_type,

+                                  group_id=msg4.group_id,

+                                  buckets=msg4.buckets)

+                                  )

+

+        verify_group_stats=sorted(verify_group_stats, key=getkey("group_id")) 

+        stats=sorted(stats, key=getkey("group_id")) 

+                                  

+        self.maxDiff=None

+        self.assertEquals(stats, verify_group_stats)

+        

+

+class L3UnicastGroup(base_tests.SimpleDataPlane):

+    def runTest(self):

+        delete_all_flows(self.controller)    

+        delete_all_groups(self.controller)    

+        

+        group_list1, msg1 = add_l2_interface_grouop(self.controller, config["port_map"].keys(), 1,  False, False)       

+        msg2=add_l3_unicast_group(self.controller, config["port_map"].keys()[0], 1, 1, [0x00,0x11,0x22,0x33,0x44,0x55], [00,0x22,0x22,0x22,0x22,0x22])

+        

+        group_list1, msg3 = add_l2_interface_grouop(self.controller, config["port_map"].keys(), 2,  False, False)               

+        msg4=add_l3_unicast_group(self.controller, config["port_map"].keys()[0], 2, 2, [0x00,0x11,0x22,0x33,0x44,0x55], [00,0x33,0x33,0x33,0x33,0x33])

+

+        stats = get_stats(self, ofp.message.group_desc_stats_request())

+        

+        verify_group_stats=[]

+        for msg in msg1:

+            verify_group_stats.append(ofp.group_desc_stats_entry(

+                                      group_type=msg.group_type,

+                                      group_id=msg.group_id,

+                                      buckets=msg.buckets)

+                                      )

+        

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=msg2.group_type,

+                                  group_id=msg2.group_id,

+                                  buckets=msg2.buckets)

+                                  )

+        

+        for msg in msg3:

+            verify_group_stats.append(ofp.group_desc_stats_entry(

+                                      group_type=msg.group_type,

+                                      group_id=msg.group_id,

+                                      buckets=msg.buckets)

+                                      )

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=msg4.group_type,

+                                  group_id=msg4.group_id,

+                                  buckets=msg4.buckets)

+                                  )

+                                  

+        verify_group_stats=sorted(verify_group_stats, key=getkey("group_id")) 

+        stats=sorted(stats, key=getkey("group_id")) 

+                                  

+        self.maxDiff=None

+        self.assertEquals(stats, verify_group_stats)  

+

+

+class L3ECMPGroup(base_tests.SimpleDataPlane):

+    def runTest(self):

+        delete_all_flows(self.controller)    

+        delete_all_groups(self.controller)    

+        

+        group_list1, msg1 = add_l2_interface_grouop(self.controller, config["port_map"].keys(), 1,  False, False)       

+        msg2=add_l3_unicast_group(self.controller, config["port_map"].keys()[0], 1, 1, [0x00,0x11,0x22,0x33,0x44,0x55], [00,0x22,0x22,0x22,0x22,0x22])

+        

+        group_list1, msg3 = add_l2_interface_grouop(self.controller, config["port_map"].keys(), 2,  False, False)               

+        msg4=add_l3_unicast_group(self.controller, config["port_map"].keys()[0], 2, 2, [0x00,0x11,0x22,0x33,0x44,0x55], [00,0x33,0x33,0x33,0x33,0x33])

+

+        group_ids=[msg2.group_id, msg4.group_id]

+        

+        msg5=add_l3_ecmp_group(self.controller, 1, group_ids)

+        

+        stats = get_stats(self, ofp.message.group_desc_stats_request())

+

+        verify_group_stats=[]

+        for msg in msg1:

+            verify_group_stats.append(ofp.group_desc_stats_entry(

+                                      group_type=msg.group_type,

+                                      group_id=msg.group_id,

+                                      buckets=msg.buckets)

+                                      )

+        

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=msg2.group_type,

+                                  group_id=msg2.group_id,

+                                  buckets=msg2.buckets)

+                                  )

+        

+        for msg in msg3:

+            verify_group_stats.append(ofp.group_desc_stats_entry(

+                                      group_type=msg.group_type,

+                                      group_id=msg.group_id,

+                                      buckets=msg.buckets)

+                                      )

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=msg4.group_type,

+                                  group_id=msg4.group_id,

+                                  buckets=msg4.buckets)

+                                  )

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=msg5.group_type,

+                                  group_id=msg5.group_id,

+                                  buckets=msg5.buckets)

+                                  )

+

+        verify_group_stats=sorted(verify_group_stats, key=getkey("group_id")) 

+        stats=sorted(stats, key=getkey("group_id")) 

+                                  

+        self.maxDiff=None

+        self.assertEquals(stats, verify_group_stats)     

+

+

+class L3InterfaceGroup(base_tests.SimpleDataPlane):

+    def runTest(self):

+        delete_all_flows(self.controller)    

+        delete_all_groups(self.controller)    

+        

+        group_list1, msg1 = add_l2_interface_grouop(self.controller, config["port_map"].keys(), 1,  False, False)               

+        msg2=add_l3_interface_group(self.controller, config["port_map"].keys()[0], 1, 1, [0x00,0x11,0x22,0x33,0x44,0x55])

+        group_list1, msg3 = add_l2_interface_grouop(self.controller, config["port_map"].keys(), 2,  False, False)                       

+        msg4=add_l3_interface_group(self.controller, config["port_map"].keys()[0], 2, 2, [0x00,0x11,0x22,0x33,0x44,0x66])

+

+        stats = get_stats(self, ofp.message.group_desc_stats_request())

+        

+        verify_group_stats=[]

+        for msg in msg1:

+            verify_group_stats.append(ofp.group_desc_stats_entry(

+                                      group_type=msg.group_type,

+                                      group_id=msg.group_id,

+                                      buckets=msg.buckets)

+                                      )

+        

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=msg2.group_type,

+                                  group_id=msg2.group_id,

+                                  buckets=msg2.buckets)

+                                  )

+        

+        for msg in msg3:

+            verify_group_stats.append(ofp.group_desc_stats_entry(

+                                      group_type=msg.group_type,

+                                      group_id=msg.group_id,

+                                      buckets=msg.buckets)

+                                      )

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=msg4.group_type,

+                                  group_id=msg4.group_id,

+                                  buckets=msg4.buckets)

+                                  )

+

+        verify_group_stats=sorted(verify_group_stats, key=getkey("group_id")) 

+        stats=sorted(stats, key=getkey("group_id")) 

+                                  

+        self.maxDiff=None

+        self.assertEquals(stats, verify_group_stats)     

+

+

+class L3McastGroup(base_tests.SimpleDataPlane):

+    def runTest(self):

+        delete_all_flows(self.controller)    

+        delete_all_groups(self.controller)    

+

+        # Vlan 3 forward to vlan 3 port 1 and 2

+        # Vlan 3 foward to vlan 1 port 1

+        # Vlan 3 foward to vlan 2 port 1     

+        # Vlan 3 foward to vlan 2 port 2             

+        group_list1_1, msg1 = add_l2_interface_grouop(self.controller, [config["port_map"].keys()[0]], 1,  False, False)               

+        msg2=add_l3_interface_group(self.controller, config["port_map"].keys()[0], 1, 1, [0x00,0x11,0x22,0x33,0x44,0x11])

+        group_list1_2, msg3 = add_l2_interface_grouop(self.controller, [config["port_map"].keys()[0]], 2,  False, False)

+        msg4=add_l3_interface_group(self.controller, config["port_map"].keys()[0], 2, 2, [0x00,0x11,0x22,0x33,0x44,0x22])

+        group_list2_1, msg5 = add_l2_interface_grouop(self.controller, [config["port_map"].keys()[1]], 2,  False, False)

+        msg6=add_l3_interface_group(self.controller, config["port_map"].keys()[1], 2, 3, [0x00,0x11,0x22,0x33,0x44,0x33])

+        group_list3, msg7 = add_l2_interface_grouop(self.controller, config["port_map"].keys(), 3,  False, False)

+        

+        group_actions=[msg2.group_id, msg4.group_id, msg6.group_id]

+        group_actions.extend(group_list3)

+

+        msg8=add_l3_mcast_group(self.controller, 3, 1, group_actions)

+        

+        stats = get_stats(self, ofp.message.group_desc_stats_request())

+        

+        verify_group_stats=[]

+        for msg in msg1:

+            verify_group_stats.append(ofp.group_desc_stats_entry(

+                                      group_type=msg.group_type,

+                                      group_id=msg.group_id,

+                                      buckets=msg.buckets)

+                                      )

+        

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=msg2.group_type,

+                                  group_id=msg2.group_id,

+                                  buckets=msg2.buckets)

+                                  )

+        

+        for msg in msg3:

+            verify_group_stats.append(ofp.group_desc_stats_entry(

+                                      group_type=msg.group_type,

+                                      group_id=msg.group_id,

+                                      buckets=msg.buckets)

+                                      )

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=msg4.group_type,

+                                  group_id=msg4.group_id,

+                                  buckets=msg4.buckets)

+                                  )

+        for msg in msg5:

+            verify_group_stats.append(ofp.group_desc_stats_entry(

+                                      group_type=msg.group_type,

+                                      group_id=msg.group_id,

+                                      buckets=msg.buckets)

+                                      )

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=msg6.group_type,

+                                  group_id=msg6.group_id,

+                                  buckets=msg6.buckets)

+                                  )                                      

+        for msg in msg7:

+            verify_group_stats.append(ofp.group_desc_stats_entry(

+                                      group_type=msg.group_type,

+                                      group_id=msg.group_id,

+                                      buckets=msg.buckets)

+                                      )                                      

+                                      

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=msg8.group_type,

+                                  group_id=msg8.group_id,

+                                  buckets=msg8.buckets)

+                                  )  

+

+        verify_group_stats=sorted(verify_group_stats, key=getkey("group_id")) 

+        stats=sorted(stats, key=getkey("group_id")) 

+                                  

+        self.maxDiff=None

+        self.assertEquals(stats, verify_group_stats)     

+        

+        

+class mpls_intf_group(base_tests.SimpleDataPlane):

+    """

+	create mpls intf group 

+	1. ref l2_intf_group

+	2. ref l2_flood_group

+	"""

+    def runTest(self):

+        delete_all_flows(self.controller)    

+        delete_all_groups(self.controller)    

+

+        test_vid=1

+        

+        #ref l2_intf_group

+        l2_intf_gid, l2_intf_msg = add_one_l2_interface_group(self.controller, config["port_map"].keys()[0], test_vid,  False, False)

+        mpls_intf_gid, mpls_intf_msg=add_mpls_intf_group(self.controller, l2_intf_gid, [0x00,0x11,0x11,0x11,0x11,0x11], [0x00,0x22,0x22,0x22,0x22,0x22], vid=test_vid, index=1)

+            

+        stats = get_stats(self, ofp.message.group_desc_stats_request())

+        

+        verify_group_stats=[]

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=l2_intf_msg.group_type,

+                                  group_id=l2_intf_msg.group_id,

+                                  buckets=l2_intf_msg.buckets)

+                                  )

+        

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=mpls_intf_msg.group_type,

+                                  group_id=mpls_intf_msg.group_id,

+                                  buckets=mpls_intf_msg.buckets)

+                                  )

+        verify_group_stats=sorted(verify_group_stats, key=getkey("group_id")) 

+        stats=sorted(stats, key=getkey("group_id"))  

+        self.assertEquals(stats, verify_group_stats)       

+              

+

+class mpls_l2_vpn_group(base_tests.SimpleDataPlane):

+    """

+	create mpls intf group 

+	1. ref l2_intf_group

+	

+	"""

+    def runTest(self):

+        delete_all_flows(self.controller)    

+        delete_all_groups(self.controller)    

+

+        test_vid=1

+        test_port=config["port_map"].keys()[0]        

+        #ref l2_intf_group

+        l2_intf_gid, l2_intf_msg = add_one_l2_interface_group(self.controller, test_port, test_vid,  False, False)

+        mpls_intf_gid, mpls_intf_msg=add_mpls_intf_group(self.controller, l2_intf_gid, [0x00,0x11,0x11,0x11,0x11,0x11], [0x00,0x22,0x22,0x22,0x22,0x22], vid=test_vid, index=1)        

+        mpls_label_gid, mpls_label_msg=add_mpls_label_group(self.controller, subtype=OFDPA_MPLS_GROUP_SUBTYPE_L2_VPN_LABEL, 

+		                                                  index=1, 

+														  ref_gid=mpls_intf_gid, 

+                                                          push_l2_header=True,

+                                                          push_vlan=True,

+                                                          push_mpls_header=True,

+                                                          push_cw=False,

+                                                          set_mpls_label=10,

+                                                          set_bos=0,

+                                                          set_tc=7,

+                                                          set_tc_from_table=False,

+														  cpy_tc_outward=False,														  

+                                                          set_ttl=250,

+                                                          cpy_ttl_outward=False,

+                                                          oam_lm_tx_count=False,

+                                                          set_pri_from_table=False

+                                                          )

+                   

+        verify_group_stats=[]

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=l2_intf_msg.group_type,

+                                  group_id=l2_intf_msg.group_id,

+                                  buckets=l2_intf_msg.buckets)

+                                  )

+        

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=mpls_intf_msg.group_type,

+                                  group_id=mpls_intf_msg.group_id,

+                                  buckets=mpls_intf_msg.buckets)

+                                  )

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=mpls_label_msg.group_type,

+                                  group_id=mpls_label_msg.group_id,

+                                  buckets=mpls_label_msg.buckets)

+                                  )                                  

+        verify_group_stats=sorted(verify_group_stats, key=getkey("group_id")) 

+        stats= get_stats(self, ofp.message.group_desc_stats_request())        

+        stats=sorted(stats, key=getkey("group_id"))  

+        #DumpGroup(stats, verify_group_stats)

+        #AssertGroup(self, stats, verify_group_stats)

+        self.assertEquals(stats, verify_group_stats)       

+		

+

+class mpls_tunnel_lable1_group(base_tests.SimpleDataPlane):

+    """

+	create mpls intf group 

+	1. ref l2_intf_group

+	

+	"""

+    def runTest(self):

+        delete_all_flows(self.controller)    

+        delete_all_groups(self.controller)    

+

+        test_vid=1

+        test_port=config["port_map"].keys()[0]        

+        #ref l2_intf_group

+        l2_intf_gid, l2_intf_msg = add_one_l2_interface_group(self.controller, test_port, test_vid,  False, False)

+        mpls_intf_gid, mpls_intf_msg=add_mpls_intf_group(self.controller, l2_intf_gid, [0x00,0x11,0x11,0x11,0x11,0x11], [0x00,0x22,0x22,0x22,0x22,0x22], vid=test_vid, index=1)                

+        mpls_label_gid, mpls_label_msg=add_mpls_label_group(self.controller, subtype=OFDPA_MPLS_GROUP_SUBTYPE_TUNNEL_LABEL1, 

+		                                                  index=1, 

+														  ref_gid=mpls_intf_gid, 

+                                                          push_l2_header=True,

+                                                          push_vlan=True,

+                                                          push_mpls_header=True,

+                                                          push_cw=True,

+                                                          set_mpls_label=10,

+                                                          set_bos=0,

+                                                          set_tc=7,

+                                                          set_tc_from_table=False,

+														  cpy_tc_outward=False,														  

+                                                          set_ttl=250,

+                                                          cpy_ttl_outward=False,

+                                                          oam_lm_tx_count=False,

+                                                          set_pri_from_table=False

+                                                          )

+            

+        stats = get_stats(self, ofp.message.group_desc_stats_request())

+        

+        verify_group_stats=[]

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=l2_intf_msg.group_type,

+                                  group_id=l2_intf_msg.group_id,

+                                  buckets=l2_intf_msg.buckets)

+                                  )

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=mpls_intf_msg.group_type,

+                                  group_id=mpls_intf_msg.group_id,

+                                  buckets=mpls_intf_msg.buckets)

+                                  )        

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=mpls_label_msg.group_type,

+                                  group_id=mpls_label_msg.group_id,

+                                  buckets=mpls_label_msg.buckets)

+                                  )

+        verify_group_stats=sorted(verify_group_stats, key=getkey("group_id")) 

+        stats=sorted(stats, key=getkey("group_id"))  

+        self.assertEquals(stats, verify_group_stats)       

+		

+

+class mpls_tunnel_lable2_group(base_tests.SimpleDataPlane):

+    """

+	create mpls intf group 

+	1. ref l2_intf_group

+	

+	"""

+    def runTest(self):

+        delete_all_flows(self.controller)    

+        delete_all_groups(self.controller)    

+

+        test_vid=1

+        test_port=config["port_map"].keys()[0]        

+        #ref l2_intf_group

+        l2_intf_gid, l2_intf_msg = add_one_l2_interface_group(self.controller, test_port, test_vid,  False, False)

+        mpls_intf_gid, mpls_intf_msg=add_mpls_intf_group(self.controller, l2_intf_gid, [0x00,0x11,0x11,0x11,0x11,0x11], [0x00,0x22,0x22,0x22,0x22,0x22], vid=test_vid, index=1)                        

+        mpls_label_gid, mpls_label_msg=add_mpls_label_group(self.controller, subtype=OFDPA_MPLS_GROUP_SUBTYPE_TUNNEL_LABEL2, 

+		                                                  index=1, 

+														  ref_gid=mpls_intf_gid, 

+                                                          push_l2_header=True,

+                                                          push_vlan=True,

+                                                          push_mpls_header=True,

+                                                          push_cw=True,

+                                                          set_mpls_label=10,

+                                                          set_bos=0,

+                                                          set_tc=7,

+                                                          set_tc_from_table=False,

+														  cpy_tc_outward=False,														  

+                                                          set_ttl=250,

+                                                          cpy_ttl_outward=False,

+                                                          oam_lm_tx_count=False,

+                                                          set_pri_from_table=False

+                                                          )

+            

+        stats = get_stats(self, ofp.message.group_desc_stats_request())

+        

+        verify_group_stats=[]

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=l2_intf_msg.group_type,

+                                  group_id=l2_intf_msg.group_id,

+                                  buckets=l2_intf_msg.buckets)

+                                  )

+        

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=mpls_intf_msg.group_type,

+                                  group_id=mpls_intf_msg.group_id,

+                                  buckets=mpls_intf_msg.buckets)

+                                  )

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=mpls_label_msg.group_type,

+                                  group_id=mpls_label_msg.group_id,

+                                  buckets=mpls_label_msg.buckets)

+                                  )                                  

+        verify_group_stats=sorted(verify_group_stats, key=getkey("group_id")) 

+        stats=sorted(stats, key=getkey("group_id"))  

+        self.assertEquals(stats, verify_group_stats)       

+		

+class mpls_swap_label_group(base_tests.SimpleDataPlane):

+    """

+	create mpls intf group 

+	1. ref l2_intf_group

+	"""

+    def runTest(self):

+        delete_all_flows(self.controller)    

+        delete_all_groups(self.controller)    

+

+        test_vid=1

+        test_port=config["port_map"].keys()[0]

+        #ref l2_intf_group

+        l2_intf_gid, l2_intf_msg = add_one_l2_interface_group(self.controller, test_port, test_vid,  False, False)

+        mpls_intf_gid, mpls_intf_msg=add_mpls_intf_group(self.controller, l2_intf_gid, [0x00,0x11,0x11,0x11,0x11,0x11], [0x00,0x22,0x22,0x22,0x22,0x22], vid=test_vid, index=1)                                

+        mpls_label_gid, mpls_label_msg=add_mpls_label_group(self.controller, subtype=OFDPA_MPLS_GROUP_SUBTYPE_SWAP_LABEL, 

+		                                                  index=1, 

+														  ref_gid=mpls_intf_gid, 

+                                                          push_l2_header=True,

+                                                          push_vlan=True,

+                                                          push_mpls_header=True,

+                                                          push_cw=True,

+                                                          set_mpls_label=10,

+                                                          set_bos=0,

+                                                          set_tc=7,

+                                                          set_tc_from_table=False,

+														  cpy_tc_outward=False,														  

+                                                          set_ttl=250,

+                                                          cpy_ttl_outward=False,

+                                                          oam_lm_tx_count=False,

+                                                          set_pri_from_table=False

+                                                          )

+            

+        stats = get_stats(self, ofp.message.group_desc_stats_request())

+        

+        verify_group_stats=[]

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=l2_intf_msg.group_type,

+                                  group_id=l2_intf_msg.group_id,

+                                  buckets=l2_intf_msg.buckets)

+                                  )

+        

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=mpls_intf_msg.group_type,

+                                  group_id=mpls_intf_msg.group_id,

+                                  buckets=mpls_intf_msg.buckets)

+                                  )

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=mpls_label_msg.group_type,

+                                  group_id=mpls_label_msg.group_id,

+                                  buckets=mpls_label_msg.buckets)

+                                  )                                    

+        verify_group_stats=sorted(verify_group_stats, key=getkey("group_id")) 

+        stats=sorted(stats, key=getkey("group_id"))  

+        self.assertEquals(stats, verify_group_stats)       

+

+

+class mpls_forwarding_group_fastfailover(base_tests.SimpleDataPlane):

+    def runTest(self):

+        delete_all_flows(self.controller)    

+        delete_all_groups(self.controller) 

+

+        test_vid=1

+        test_port=config["port_map"].keys()[0]

+        #ref l2_intf_group

+        l2_intf_gid, l2_intf_msg = add_one_l2_interface_group(self.controller, test_port, test_vid,  False, False)

+        mpls_intf_gid, mpls_intf_msg=add_mpls_intf_group(self.controller, l2_intf_gid, [0x00,0x11,0x11,0x11,0x11,0x11], [0x00,0x22,0x22,0x22,0x22,0x22], vid=test_vid, index=1)                                

+        mpls_label_gid, mpls_label_msg=add_mpls_label_group(self.controller, subtype=OFDPA_MPLS_GROUP_SUBTYPE_SWAP_LABEL, 

+		                                                  index=1, 

+														  ref_gid=mpls_intf_gid, 

+                                                          push_l2_header=True,

+                                                          push_vlan=True,

+                                                          push_mpls_header=True,

+                                                          push_cw=True,

+                                                          set_mpls_label=10,

+                                                          set_bos=0,

+                                                          set_tc=7,

+                                                          set_tc_from_table=False,

+														  cpy_tc_outward=False,														  

+                                                          set_ttl=250,

+                                                          cpy_ttl_outward=False,

+                                                          oam_lm_tx_count=False,

+                                                          set_pri_from_table=False

+                                                          )        

+        mpls_fwd_gid, mpls_fwd_msg=add_mpls_forwarding_group(self.controller, 

+                                                             subtype=OFDPA_MPLS_GROUP_SUBTYPE_FAST_FAILOVER_GROUP, 

+                                                             index=1, 

+                                                             ref_gids=[mpls_label_gid], 

+                                                             watch_port=test_port, 

+                                                             watch_group=ofp.OFPP_ANY, 

+                                                             push_vlan=None,

+                                                             pop_vlan=None,

+                                                             set_vid=None)

+            

+        stats = get_stats(self, ofp.message.group_desc_stats_request())

+        

+        verify_group_stats=[]

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=l2_intf_msg.group_type,

+                                  group_id=l2_intf_msg.group_id,

+                                  buckets=l2_intf_msg.buckets)

+                                  )

+        

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=mpls_intf_msg.group_type,

+                                  group_id=mpls_intf_msg.group_id,

+                                  buckets=mpls_intf_msg.buckets)

+                                  )

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=mpls_label_msg.group_type,

+                                  group_id=mpls_label_msg.group_id,

+                                  buckets=mpls_label_msg.buckets)

+                                  )

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=mpls_fwd_msg.group_type,

+                                  group_id=mpls_fwd_msg.group_id,

+                                  buckets=mpls_fwd_msg.buckets)

+                                  )                                    

+        verify_group_stats=sorted(verify_group_stats, key=getkey("group_id")) 

+        stats=sorted(stats, key=getkey("group_id"))  

+        self.assertEquals(stats, verify_group_stats)       

+

+

+class mpls_forwarding_group_ecmp(base_tests.SimpleDataPlane):

+    """chip not support to bind flow on trident2 

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)    

+        delete_all_groups(self.controller) 

+

+        test_vid=1

+        mpls_intf_msgs=[]

+        mpls_intf_gids=[]

+        l2_intf_msgs=[]

+        index=1

+        #ref l2_intf_group

+        for port in config["port_map"].keys():

+            l2_intf_gid, l2_intf_msg = add_one_l2_interface_group(self.controller, port, test_vid,  False, False)

+            l2_intf_msgs.append(l2_intf_msg)            

+            mpls_intf_gid, mpls_intf_msg=add_mpls_intf_group(self.controller, l2_intf_gid, [0x00,0x11,0x11,0x11,0x11,0x11], [0x00,0x22,0x22,0x22,0x22,0x22], vid=test_vid, index=index)

+            index=index+1

+            mpls_intf_msgs.append(mpls_intf_msg)

+            mpls_intf_gids.append(mpls_intf_gid)

+            

+        mpls_fwd_gid, mpls_fwd_msg=add_mpls_forwarding_group(self.controller, 

+                                                             subtype=OFDPA_MPLS_GROUP_SUBTYPE_ECMP, 

+                                                             index=1, 

+                                                             ref_gids=mpls_intf_gids, 

+                                                             watch_port=None, 

+                                                             watch_group=None,

+                                                             push_vlan=None,

+                                                             pop_vlan=None,

+                                                             set_vid=None)

+            

+        stats = get_stats(self, ofp.message.group_desc_stats_request())

+        

+        verify_group_stats=[]

+        for msg in l2_intf_msgs:

+            verify_group_stats.append(ofp.group_desc_stats_entry(

+                                      group_type=msg.group_type,

+                                      group_id=msg.group_id,

+                                      buckets=msg.buckets)

+                                      )

+        

+        for msg in mpls_intf_msgs:

+            verify_group_stats.append(ofp.group_desc_stats_entry(

+                                      group_type=msg.group_type,

+                                      group_id=msg.group_id,

+                                      buckets=msg.buckets)

+                                      )

+

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=mpls_fwd_msg.group_type,

+                                  group_id=mpls_fwd_msg.group_id,

+                                  buckets=mpls_fwd_msg.buckets)

+                                  )                                    

+        verify_group_stats=sorted(verify_group_stats, key=getkey("group_id")) 

+        stats=sorted(stats, key=getkey("group_id"))  

+        self.assertEquals(stats, verify_group_stats)       

+

+

+class mpls_forwarding_group_l2tag(base_tests.SimpleDataPlane):

+    """chip not support

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)    

+        delete_all_groups(self.controller) 

+

+        test_vid=1

+        test_port=config["port_map"].keys()[0]

+        index=1

+        #ref l2_intf_group        

+        l2_intf_gid, l2_intf_msg = add_one_l2_interface_group(self.controller, test_port, test_vid,  False, False)

+

+        mpls_fwd_gid, mpls_fwd_msg=add_mpls_forwarding_group(self.controller, 

+                                                             subtype=OFDPA_MPLS_GROUP_SUBTYPE_L2_TAG, 

+                                                             index=1, 

+                                                             ref_gids=l2_intf_gid, 

+                                                             watch_port=None, 

+                                                             watch_group=None,

+                                                             push_vlan=None,

+                                                             pop_vlan=None,

+                                                             set_vid=1)

+            

+        stats = get_stats(self, ofp.message.group_desc_stats_request())

+        

+        verify_group_stats=[]

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=l2_intf_msg.group_type,

+                                  group_id=l2_intf_msg.group_id,

+                                  buckets=l2_intf_msg.buckets)

+                                  )

+        

+        verify_group_stats.append(ofp.group_desc_stats_entry(

+                                  group_type=mpls_fwd_msg.group_type,

+                                  group_id=mpls_fwd_msg.group_id,

+                                  buckets=mpls_fwd_msg.buckets)

+                                  )                                    

+        verify_group_stats=sorted(verify_group_stats, key=getkey("group_id")) 

+        stats=sorted(stats, key=getkey("group_id"))  

+

+        self.assertEquals(stats, verify_group_stats)  
\ No newline at end of file
diff --git a/Fabric/Utilities/accton/nat.py b/Fabric/Utilities/accton/nat.py
new file mode 100755
index 0000000..5557d60
--- /dev/null
+++ b/Fabric/Utilities/accton/nat.py
@@ -0,0 +1,293 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+"""

+Nat Test

+

+Test each flow table can set entry, and packet rx correctly.

+"""

+

+import logging

+

+from oftest import config

+import oftest.base_tests as base_tests

+import ofp

+from oftest.testutils import *

+from accton_util import *

+

+class dnat(base_tests.SimpleDataPlane):

+    """

+    [DNAT]

+      DNAT (inbound)

+

+    Inject  eth 1/3 DA000000000200, SA000000000201, Tag 200, SIP 200.0.0.1, DIP 100.0.0.01, Sport 2828, Dport 5000

+    Output  eth 1/1 DA000000000101, SA000000000100, Tag 100, SIP 200.0.0.1, DIP 10.0.0.01, Sport 2828, Dport 2000

+

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=3,vlan_vid=0x10c8/0x1fff goto:20

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x640001 group=any,port=any,weight=0 output=1

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x23000001 group=any,port=any,weight=0 set_field=eth_src=00:00:00:00:01:00,set_field=eth_dst=00:00:00:00:01:01,set_field=vlan_vid=100,group=0x640001

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=20,cmd=add,prio=201 vlan_vid=200/0xfff,eth_dst=00:00:00:00:02:00,eth_type=0x0800 goto:28

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=28,cmd=add,prio=281 eth_type=0x800,ip_dst=100.0.0.1,ip_proto=6,tcp_dst=5000 write:set_field=ip_dst:10.0.0.1,set_field=tcp_dst:2000,group=0x23000001 goto:60

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+        

+        add_one_vlan_table_flow(self.controller, input_port, vlan_id=200, vrf=0, flag=VLAN_TABLE_FLAG_ONLY_BOTH, send_barrier=False)           

+        add_termination_flow(self.controller, input_port, 0x0800, [0x00,0x00,0x00,0x00,0x02,0x00], 200, goto_table=28, send_barrier=False)        

+        

+        add_one_l2_interface_group(self.controller, port=output_port, vlan_id=100, is_tagged=True, send_barrier=False)

+        msg1=add_l3_unicast_group(self.controller, port=output_port, vlanid=100, id=0x3000001, src_mac=[0x00,0x00,0x00,0x00,0x01,0x00], dst_mac=[0x00,0x00,0x00,0x00,0x01,0x01])

+        add_dnat_flow(self.controller, eth_type=0x0800, ip_dst=0x64000001, ip_proto=6, tcp_dst=5000, set_ip_dst=0x0a000001, set_tcp_dst=2000, action_group_id=msg1.group_id)

+

+        input_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst="00:00:00:00:02:00",

+                                       eth_src="00:00:00:00:02:01",

+                                       dl_vlan_enable = True,

+                                       vlan_vid = 200,

+                                       ip_ttl=64,                                       

+                                       ip_src="200.0.0.1",

+                                       ip_dst='100.0.0.1',

+                                       tcp_dport=5000)

+        output_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst="00:00:00:00:01:01",

+                                       eth_src="00:00:00:00:01:00",

+                                       dl_vlan_enable = True,

+                                       vlan_vid = 100,                                       

+                                       ip_ttl=63,                                       

+                                       ip_src="200.0.0.1",

+                                       ip_dst='10.0.0.1',

+                                       tcp_dport=2000)

+                                       

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+         

+        

+        

+class dnatEcmp(base_tests.SimpleDataPlane):

+    """

+    [DNAT ECMP]

+      DNAT (inbound) with ECMP

+

+    Inject  eth 1/3 DA000000000200, SA000000000201, Tag 200, SIP 200.0.0.1, DIP 100.0.0.01, Sport 2828, Dport 5000 [increase SIP]

+    Output  eth 1/1 DA000000000101, SA000000000100, Tag 100, SIP 200.0.0.X, DIP 10.0.0.01, Sport 2828, Dport 2000

+    Output  eth 1/5 DA000005224466, SA000005223355, Tag 2, SIP 200.0.0.X, DIP 10.0.0.01, Sport 2828, Dport 2000

+

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=3,vlan_vid=0x10c8/0x1fff goto:20

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x640001 group=any,port=any,weight=0 output=1

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x23000001 group=any,port=any,weight=0 set_field=eth_src=00:00:00:00:01:00,set_field=eth_dst=00:00:00:00:01:01,set_field=vlan_vid=100,group=0x640001

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20005 group=any,port=any,weight=0 output=5    

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x23000005 group=any,port=any,weight=0 set_field=eth_src=00:00:05:22:33:55,set_field=eth_dst=00:00:05:22:44:66,set_field=vlan_vid=2,group=0x20005    

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=sel,group=0x71000001 group=any,port=any,weight=0 group=0x23000001 group=any,port=any,weight=0 group=0x23000005    

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=20,cmd=add,prio=201 vlan_vid=200/0xfff,eth_dst=00:00:00:00:02:00,eth_type=0x0800 goto:28

+    

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=28,cmd=add,prio=281 eth_type=0x800,ip_dst=100.0.0.1,ip_proto=6,tcp_dst=5000 write:set_field=ip_dst:10.0.0.1,set_field=tcp_dst:2000,group=0x71000001 goto:60

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = config["port_map"].keys()

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+        output_port2 = test_ports[2]

+

+        add_one_vlan_table_flow(self.controller, input_port, vlan_id=200, vrf=0, flag=VLAN_TABLE_FLAG_ONLY_TAG, send_barrier=False)   

+        add_one_l2_interface_group(self.controller, port=output_port, vlan_id=100, is_tagged=True, send_barrier=False)

+        #Bits 27:24 is for realm id, so unicast group id give 0x3000001

+        msg1=add_l3_unicast_group(self.controller, port=output_port, vlanid=100, id=0x3000001, src_mac=[0x00,0x00,0x00,0x00,0x01,0x00], dst_mac=[0x00,0x00,0x00,0x00,0x01,0x01])

+        add_one_l2_interface_group(self.controller, port=output_port2, vlan_id=2, is_tagged=True, send_barrier=False)

+        #Bits 27:24 is for realm id, so unicast group id give 0x3000005

+        msg2=add_l3_unicast_group(self.controller, port=output_port2, vlanid=2, id=0x3000005, src_mac=[0x00,0x00,0x05,0x22,0x33,0x55], dst_mac=[0x00,0x00,0x05,0x22,0x44,0x66])

+        ecmp=add_l3_ecmp_group(self.controller, id=0x1000001, l3_ucast_groups=[msg1.group_id, msg2.group_id])

+        add_termination_flow(self.controller, 0, 0x0800, [0x00,0x00,0x00,0x00,0x02,0x00], 200, goto_table=28, send_barrier=False)

+        add_dnat_flow(self.controller, eth_type=0x0800, ip_dst=0x64000001, ip_proto=6, tcp_dst=5000, set_ip_dst=0x0a000001, set_tcp_dst=2000, action_group_id=ecmp.group_id)

+        

+        

+        input_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst="00:00:00:00:02:00",

+                                       eth_src="00:00:00:00:02:01",

+                                       dl_vlan_enable = True,

+                                       vlan_vid = 200,

+                                       ip_ttl=64,                                       

+                                       ip_src="200.0.0.1",

+                                       ip_dst='100.0.0.1',

+                                       tcp_dport=5000)

+        output_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst="00:00:00:00:01:01",

+                                       eth_src="00:00:00:00:01:00",

+                                       dl_vlan_enable = True,

+                                       vlan_vid = 100,                                       

+                                       ip_ttl=63,                                       

+                                       ip_src="200.0.0.1",

+                                       ip_dst='10.0.0.1',

+                                       tcp_dport=2000)

+        output_pkt2 = simple_tcp_packet(pktlen=100, 

+                                       eth_dst="00:00:05:22:44:66",

+                                       eth_src="00:00:05:22:33:55",

+                                       dl_vlan_enable = True,

+                                       vlan_vid = 2,                                       

+                                       ip_ttl=63,                                       

+                                       ip_src="200.0.0.1",

+                                       ip_dst='10.0.0.1',

+                                       tcp_dport=2000)

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt2), output_port2)

+        #self.dataplane.send(input_port, str(input_pkt))

+        #verify_packet(self, str(output_pkt2), output_port2)

+        

+class snat_ecmp(base_tests.SimpleDataPlane):

+    """

+    [SNAT ECMP]

+      SNAT (outbound) with ECMP

+

+    Inject  eth 1/1 DA000000000100, SA000000000101, Tag 100, SIP 10.0.0.1, DIP 200.0.0.01, Sport 2000, Dport 2828 [increase DIP]

+    Output  eth 1/3 DA000000000200, SA000000000201, Tag 200, SIP 100.0.0.1, DIP 200.0.0.X, Sport 5000, Dport 2828

+    Output  eth 1/5 DA000000000500, SA000000000501, Tag 5, SIP 100.0.0.1, DIP 200.0.0.X, Sport 5000, Dport 2828

+

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=1,vlan_vid=0x1064/0x1fff goto:20

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=20,cmd=add,prio=201 vlan_vid=100/0xfff,eth_dst=00:00:00:00:01:00,eth_type=0x0800 goto:29

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0xC80003 group=any,port=any,weight=0 output=3   

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x22000002 group=any,port=any,weight=0 set_field=eth_src=00:00:00:00:02:00,set_field=eth_dst=00:00:00:00:02:01,set_field=vlan_vid=200,group=0xC80003    

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x50005 group=any,port=any,weight=0 output=5

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x22000005 group=any,port=any,weight=0 set_field=eth_src=00:00:00:00:05:00,set_field=eth_dst=00:00:00:00:05:01,set_field=vlan_vid=5,group=0x50005

+    

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=sel,group=0x71000001 group=any,port=any,weight=0 group=0x22000002 group=any,port=any,weight=0 group=0x22000005

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=29,cmd=add,prio=291 eth_type=0x800,ip_src=10.0.0.1,ip_proto=6,tcp_src=2000 write:set_field=ip_src:100.0.0.1,set_field=tcp_src:5000 goto:30

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=30,cmd=add,prio=301 eth_type=0x0800,ip_dst=200.0.0.1/255.255.255.0 write:group=0x71000001 goto:60

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+        output_port2 = test_ports[2]

+        

+        add_one_vlan_table_flow(self.controller, input_port, vlan_id=100, vrf=0, flag=VLAN_TABLE_FLAG_ONLY_TAG, send_barrier=False)   

+        add_termination_flow(self.controller, 0, 0x0800, [0x00,0x00,0x00,0x00,0x01,0x00], 100, goto_table=29, send_barrier=False)

+        add_one_l2_interface_group(self.controller, port=output_port, vlan_id=200, is_tagged=True, send_barrier=False)

+        #Bits 27:24 is for realm id, so unicast group id give 0x2000002

+        msg1=add_l3_unicast_group(self.controller, port=output_port, vlanid=200, id=0x2000002, src_mac=[0x00,0x00,0x00,0x00,0x02,0x00], dst_mac=[0x00,0x00,0x00,0x00,0x02,0x01])

+        

+        add_one_l2_interface_group(self.controller, port=output_port2, vlan_id=5, is_tagged=True, send_barrier=False)

+        #Bits 27:24 is for realm id, so unicast group id give 0x2000002

+        msg2=add_l3_unicast_group(self.controller, port=output_port2, vlanid=5, id=0x2000005, src_mac=[0x00,0x00,0x00,0x00,0x05,0x00], dst_mac=[0x00,0x00,0x00,0x00,0x05,0x01])

+

+        ecmp=add_l3_ecmp_group(self.controller, id=0x1000001, l3_ucast_groups=[msg1.group_id, msg2.group_id])

+        add_snat_flow(self.controller, 0x0800, 0x0a000001, 6, 2000, 0x64000001, 5000)

+        add_unicast_routing_flow(self.controller, 0x0800, 0xc8000001, 0xffffff00, ecmp.group_id, vrf=0, send_barrier=False)

+

+        input_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst="00:00:00:00:01:00",

+                                       eth_src="00:00:00:00:01:01",

+                                       dl_vlan_enable = True,

+                                       vlan_vid = 100,

+                                       ip_ttl=64,                                       

+                                       ip_src='10.0.0.1',

+                                       ip_dst="200.0.0.1",

+                                       tcp_sport=2000)

+        output_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst="00:00:00:00:02:01",

+                                       eth_src="00:00:00:00:02:00",

+                                       dl_vlan_enable = True,

+                                       vlan_vid = 200,                                       

+                                       ip_ttl=63,                                       

+                                       ip_src="100.0.0.1",

+                                       ip_dst='200.0.0.1',

+                                       tcp_sport=5000)

+        output_pkt2 = simple_tcp_packet(pktlen=100, 

+                                       eth_dst="00:00:00:00:05:01",

+                                       eth_src="00:00:00:00:05:00",

+                                       dl_vlan_enable = True,

+                                       vlan_vid = 5,                                       

+                                       ip_ttl=63,                                       

+                                       ip_src="100.0.0.1",

+                                       ip_dst='200.0.0.1',

+                                       tcp_sport=5000)

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+        #self.dataplane.send(input_port, str(input_pkt))

+        #verify_packet(self, str(output_pkt2), output_port2)

+        

+"""just for verify it can work after nat ecmp"""

+class l3Route(base_tests.SimpleDataPlane):

+    """

+    [L3 unicast route]

+      Do unicast route and output to specified port

+    

+    Inject  eth 1/3 Tag2, SA000000112233, DA7072cf7cf3a3, SIP 192.168.1.100, DIP 192.168.2.2

+    Output  eth 1/1 Tag3, SA 000004223355, DA 000004224466

+    

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=0,cmd=add,prio=1 in_port=0/0xffff0000 goto:10

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=3,vlan_vid=0x1002/0x1fff goto:20

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=20,cmd=add,prio=201 in_port=3,vlan_vid=2/0xfff,eth_dst=70:72:cf:7c:f3:a3,eth_type=0x0800 goto:30

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x30001 group=any,port=any,weight=0 output=1

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20000003 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:55,set_field=eth_dst=00:00:04:22:44:66,set_field=vlan_vid=3,group=0x30001

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=30,cmd=add,prio=301 eth_type=0x0800,ip_dst=192.168.2.2/255.255.255.0 write:group=0x20000003 goto:60

+    """

+    def runTest(self):   

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]    

+

+        add_port_table_flow(self.controller, is_overlay=False)

+        add_one_vlan_table_flow(self.controller, input_port, vlan_id=2, vrf=0, flag=VLAN_TABLE_FLAG_ONLY_TAG, send_barrier=False)   

+        add_termination_flow(self.controller, input_port, 0x0800, [0x70, 0x72, 0xcf, 0x7c, 0xf3, 0xa3], 2, send_barrier=False)

+        add_one_l2_interface_group(self.controller, port=output_port, vlan_id=3, is_tagged=True, send_barrier=False)

+        msg=add_l3_unicast_group(self.controller, port=output_port, vlanid=3, id=3, src_mac=[0x00,0x00,0x04,0x22,0x33,0x55], dst_mac=[0x00,0x00,0x04,0x22,0x44,0x66])

+        add_unicast_routing_flow(self.controller, 0x0800, 0xc0a80202, 0xffffff00, msg.group_id)

+

+        #verify tx/rx packet

+        input_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst="70:72:cf:7c:f3:a3",

+                                       eth_src="00:00:00:00:02:01",

+                                       dl_vlan_enable = True,

+                                       vlan_vid = 2,

+                                       ip_ttl=64,                                       

+                                       ip_src="200.0.0.1",

+                                       ip_dst='192.168.2.2')

+        output_pkt = simple_tcp_packet(pktlen=100, 

+                                       eth_dst="00:00:04:22:44:66",

+                                       eth_src="00:00:04:22:33:55",

+                                       dl_vlan_enable = True,

+                                       vlan_vid = 3,                                       

+                                       ip_ttl=63,                                       

+                                       ip_src="200.0.0.1",

+                                       ip_dst='192.168.2.2')        

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)        

+        

+        

+        

+        

+        

+        

+        
\ No newline at end of file
diff --git a/Fabric/Utilities/accton/vxlan_flow_test.py b/Fabric/Utilities/accton/vxlan_flow_test.py
new file mode 100755
index 0000000..b57b98e
--- /dev/null
+++ b/Fabric/Utilities/accton/vxlan_flow_test.py
@@ -0,0 +1,1281 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+"""

+Flow Test

+

+Test each flow table can set entry, and packet rx correctly.

+"""

+

+import logging

+

+from oftest import config

+import oftest.base_tests as base_tests

+import ofp

+from oftest.testutils import *

+from accton_util import *

+import oftest.parse as decode

+       

+class VxlanConfigNetconf(base_tests.SimpleDataPlane):

+    """

+    Verify netconf to configure Vxlan port

+	"""

+    def runTest(self):

+        if config["switch_ip"] == None:

+            logging.error("Doesn't configure switch IP")		

+            return

+			

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+        

+        #paramaters

+        access_port_vid=1

+        access_phy_port=1

+        access_lport=0x10001

+        vnid=103

+        next_hop_id=1

+        next_hop_id_mcast=2

+        dst_mac="00:00:11:22:22:11"

+        mcast_ipv4="224.1.1.1"

+        dst_mac_mcast="01:00:5e:01:01:01"

+        network_port_phy_port=2

+        network_lport=0x10002

+        network_port_vlan=2

+        network_port_sip="192.168.1.1"

+        network_port_dip="192.168.2.1"

+

+        xml_before=get_edit_config(config["switch_ip"])

+		#get datapath_id from feature message

+        feature_reply=get_featureReplay(self)	

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id_mcast, 

+		                                          dst_mac=dst_mac_mcast, 

+												  phy_port=network_port_phy_port, 

+												  vlan=network_port_vlan)        

+        logging.info("config NextHop %d, DST_MAC %s, PHY %d, VLAN %d", next_hop_id_mcast, dst_mac_mcast, network_port_phy_port, network_port_vlan);

+        assert(send_edit_config(config["switch_ip"], next_hop_conf_xml) == True)                

+        

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id, 

+		                                          dst_mac=dst_mac, 

+												  phy_port=network_port_phy_port, 

+												  vlan=network_port_vlan)

+        logging.info("config NextHop %d, DST_MAC %s, PHY %d, VLAN %d", next_hop_id, dst_mac, network_port_phy_port, network_port_vlan);

+        assert(send_edit_config(config["switch_ip"], next_hop_conf_xml) == True)                                                  

+        

+        vni_config_xml=get_vni_config_xml(vni_id=vnid, 

+                                          mcast_ipv4=mcast_ipv4, 

+                                          next_hop_id=next_hop_id_mcast)

+        logging.info("config VNI %lx", vnid);

+        assert(send_edit_config(config["switch_ip"], vni_config_xml) == True)

+            

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                        lport=access_lport, phy_port=access_phy_port, 

+                                        vlan=access_port_vid, vnid=vnid)

+        logging.info("config VTAP 0x%lx, PHY %d, VID %d, VNID %lx", access_lport, access_phy_port, access_port_vid, vnid);

+        assert(send_edit_config(config["switch_ip"], vtap_conf_xml) == True)

+

+        vtep_conf_xml=get_vtep_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                                lport=network_lport, 

+                                                src_ip=network_port_sip, dst_ip=network_port_dip,

+                                                next_hop_id=next_hop_id, 

+                                                vnid=vnid)												

+        logging.info("config VTEP 0x%lx, SRC_IP %s, DST_IP %s, NEXTHOP_ID %d", network_lport, network_port_sip, network_port_dip, next_hop_id);                                                

+        assert(send_edit_config(config["switch_ip"], vtep_conf_xml) == True)            

+            

+        get_edit_config(config["switch_ip"])

+

+		#exit verification so clear all configuration

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+		                                        lport=access_lport, phy_port=access_phy_port, 

+												vlan=access_port_vid, vnid=vnid, operation="delete")

+        assert(send_edit_config(config["switch_ip"], vtap_conf_xml) == True)

+        

+        vtep_conf_xml=get_vtep_lport_config_xml(dp_id=feature_reply.datapath_id, 

+		                                        lport=network_lport, 

+												src_ip=network_port_sip, dst_ip=network_port_dip, 

+												next_hop_id=next_hop_id, 

+												vnid=vnid, operation="delete")												

+        assert(send_edit_config(config["switch_ip"], vtep_conf_xml) == True)

+

+        vni_config_xml=get_vni_config_xml(vni_id=vnid, 

+                                          mcast_ipv4=mcast_ipv4, 

+                                          next_hop_id=next_hop_id_mcast, operation="delete")

+        assert(send_edit_config(config["switch_ip"], vni_config_xml) == True)

+

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id, 

+		                                          dst_mac=dst_mac, 

+												  phy_port=network_port_phy_port, 

+												  vlan=network_port_vlan, operation="delete")

+        assert(send_edit_config(config["switch_ip"], next_hop_conf_xml) == True)

+

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id_mcast, 

+		                                          dst_mac=dst_mac_mcast, 

+												  phy_port=network_port_phy_port, 

+												  vlan=network_port_vlan, operation="delete")

+        assert(send_edit_config(config["switch_ip"], next_hop_conf_xml) == True)            

+

+        xml_after=get_edit_config(config["switch_ip"])

+        #logging.info("xml_before\n %s", xml_before)

+        #logging.info("xml_after\n %s", xml_after)

+        #netopeer may have problem on xml process

+        #assert(xml_before == xml_after)

+        

+class OverlayFloodGroup(base_tests.SimpleDataPlane):

+    """

+	create two lport

+	"""

+    def runTest(self):

+        """

+        first verify flood over unicast, 

+        second verify flood over mcast

+        """

+        if config["switch_ip"] == None:

+            logging.error("Doesn't configure switch IP")		

+            return

+			

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+        #paramaters

+        access_port_vid=1

+        access_phy_port=1

+        access_lport=0x10001

+        vnid=103

+        next_hop_id=1

+        next_hop_id_mcast=2

+        dst_mac="00:00:11:22:22:11"

+        mcast_ipv4="224.1.1.1"

+        dst_mac_mcast="01:00:5e:01:01:01"

+        network_port_phy_port=2

+        network_lport=0x10002

+        network_port_vlan=2

+        network_port_sip="192.168.1.1"

+        network_port_dip="192.168.2.1"

+		

+        feature_reply=get_featureReplay(self)	

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id_mcast, 

+		                                          dst_mac=dst_mac_mcast, 

+												  phy_port=network_port_phy_port, 

+												  vlan=network_port_vlan)        

+        logging.info("config NextHop %d, DST_MAC %s, PHY %d, VLAN %d", next_hop_id, dst_mac, network_port_phy_port, network_port_vlan);

+        assert(send_edit_config(config["switch_ip"], next_hop_conf_xml) == True)                                                  

+        vni_config_xml=get_vni_config_xml(vni_id=vnid, mcast_ipv4=mcast_ipv4, next_hop_id=next_hop_id_mcast)

+        logging.info("config VNI %lx", vnid);

+        assert(send_edit_config(config["switch_ip"], vni_config_xml) == True)

+            

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                        lport=access_lport, phy_port=access_phy_port, 

+                                        vlan=access_port_vid, vnid=vnid)

+        logging.info("config VTAP 0x%lx, PHY %d, VID %d, VNID %lx", access_lport, access_phy_port, access_port_vid, vnid);

+        assert(send_edit_config(config["switch_ip"], vtap_conf_xml) == True)

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id, 

+		                                          dst_mac=dst_mac, 

+												  phy_port=network_port_phy_port, 

+												  vlan=network_port_vlan)

+        logging.info("config NextHop %d, DST_MAC %s, PHY %d, VLAN %d", next_hop_id, dst_mac, network_port_phy_port, network_port_vlan);

+        assert(send_edit_config(config["switch_ip"], next_hop_conf_xml) == True)

+        vtep_conf_xml=get_vtep_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                                lport=network_lport, 

+                                                src_ip=network_port_sip, dst_ip=network_port_dip,

+                                                next_hop_id=next_hop_id, 

+                                                vnid=vnid)												

+        logging.info("config VTEP 0x%lx, SRC_IP %s, DST_IP %s, NEXTHOP_ID %d", network_lport, network_port_sip, network_port_dip, next_hop_id);                                                

+        assert(send_edit_config(config["switch_ip"], vtep_conf_xml) == True)

+

+        #add flow over unicast group

+        msg=add_l2_overlay_flood_over_unicast_tunnel_group(self.controller, vnid, [access_lport, network_lport], 1)

+        #verify

+        stats = get_stats(self, ofp.message.group_desc_stats_request())

+        verify_group_stats=(ofp.group_desc_stats_entry(

+    	                    group_type=msg.group_type,

+						    group_id=msg.group_id,

+						    buckets=msg.buckets))

+

+        self.assertEquals(stats, [verify_group_stats])

+        #clear all group

+        delete_all_groups(self.controller)

+		#

+		#flood over mcast

+        msg=add_l2_overlay_flood_over_mcast_tunnel_group(self.controller, vnid, [access_lport, network_lport], 1)

+

+        stats = get_stats(self, ofp.message.group_desc_stats_request())

+ 

+        verify_group_stats=(ofp.group_desc_stats_entry(

+    	                    group_type=msg.group_type,

+						    group_id=msg.group_id,

+						    buckets=msg.buckets))

+

+        self.assertEquals(stats, [verify_group_stats])

+        #clear all group

+        delete_all_groups(self.controller)

+		#exit verification so clear all configuration

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+		                                        lport=access_lport, phy_port=access_phy_port, 

+												vlan=access_port_vid, vnid=vnid, operation="delete")

+        assert(send_edit_config(config["switch_ip"], vtap_conf_xml) == True)

+        vtep_conf_xml=get_vtep_lport_config_xml(dp_id=feature_reply.datapath_id, 

+		                                        lport=network_lport, 

+												src_ip=network_port_sip, dst_ip=network_port_dip, 

+												next_hop_id=next_hop_id, 

+												vnid=vnid, operation="delete")												

+        assert(send_edit_config(config["switch_ip"], vtep_conf_xml) == True)

+

+        vni_config_xml=get_vni_config_xml(vni_id=vnid, mcast_ipv4=None, next_hop_id=None, operation="delete")

+        assert(send_edit_config(config["switch_ip"], vni_config_xml) == True)

+

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id, 

+		                                          dst_mac=dst_mac, 

+												  phy_port=network_port_phy_port, 

+												  vlan=network_port_vlan, operation="delete")

+        assert(send_edit_config(config["switch_ip"], next_hop_conf_xml) == True)

+

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id_mcast, 

+		                                          dst_mac=dst_mac_mcast, 

+												  phy_port=network_port_phy_port, 

+												  vlan=network_port_vlan, operation="delete")

+        assert(send_edit_config(config["switch_ip"], next_hop_conf_xml) == True)            

+

+class OverlayMcastGroup(base_tests.SimpleDataPlane):

+    """

+	create two lport

+	"""

+    def runTest(self):

+        if config["switch_ip"] == None:

+            logging.error("Doesn't configure switch IP")		

+            return

+			

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+        #paramaters

+        access_port_vid=1

+        access_phy_port=1

+        access_lport=0x10001

+        vnid=103

+        next_hop_id=1

+        next_hop_id_mcast=2

+        dst_mac="00:00:11:22:22:11"

+        mcast_ipv4="224.1.1.1"

+        dst_mac_mcast="01:00:5e:01:01:01"

+        network_port_phy_port=2

+        network_lport=0x10002

+        network_port_vlan=2

+        network_port_sip="192.168.1.1"

+        network_port_dip="192.168.2.1"

+		

+        feature_reply=get_featureReplay(self)	

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id_mcast, 

+		                                          dst_mac=dst_mac_mcast, 

+												  phy_port=network_port_phy_port, 

+												  vlan=network_port_vlan)        

+        logging.info("config NextHop %d, DST_MAC %s, PHY %d, VLAN %d", next_hop_id, dst_mac, network_port_phy_port, network_port_vlan);

+        assert(send_edit_config(config["switch_ip"], next_hop_conf_xml) == True)                                                  

+        vni_config_xml=get_vni_config_xml(vni_id=vnid, mcast_ipv4=mcast_ipv4, next_hop_id=next_hop_id_mcast)

+        logging.info("config VNI %lx", vnid);

+        assert(send_edit_config(config["switch_ip"], vni_config_xml) == True)

+            

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                        lport=access_lport, phy_port=access_phy_port, 

+                                        vlan=access_port_vid, vnid=vnid)

+        logging.info("config VTAP 0x%lx, PHY %d, VID %d, VNID %lx", access_lport, access_phy_port, access_port_vid, vnid);

+        assert(send_edit_config(config["switch_ip"], vtap_conf_xml) == True)

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id, 

+		                                          dst_mac=dst_mac, 

+												  phy_port=network_port_phy_port, 

+												  vlan=network_port_vlan)

+        logging.info("config NextHop %d, DST_MAC %s, PHY %d, VLAN %d", next_hop_id, dst_mac, network_port_phy_port, network_port_vlan);

+        assert(send_edit_config(config["switch_ip"], next_hop_conf_xml) == True)

+        vtep_conf_xml=get_vtep_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                                lport=network_lport, 

+                                                src_ip=network_port_sip, dst_ip=network_port_dip,

+                                                next_hop_id=next_hop_id, 

+                                                vnid=vnid)												

+        logging.info("config VTEP 0x%lx, SRC_IP %s, DST_IP %s, NEXTHOP_ID %d", network_lport, network_port_sip, network_port_dip, next_hop_id);                                                

+        assert(send_edit_config(config["switch_ip"], vtep_conf_xml) == True)

+

+        #add flow over unicast group

+        msg=msg=add_l2_overlay_mcast_over_unicast_tunnel_group(self.controller, vnid, [access_lport, network_lport], 1)

+        #verify

+        stats = get_stats(self, ofp.message.group_desc_stats_request())

+        verify_group_stats=(ofp.group_desc_stats_entry(

+    	                    group_type=msg.group_type,

+						    group_id=msg.group_id,

+						    buckets=msg.buckets))

+

+        self.assertEquals(stats, [verify_group_stats])

+        #clear all group

+        delete_all_groups(self.controller)

+		#

+		#flood over mcast

+        msg=add_l2_overlay_mcast_over_mcast_tunnel_group(self.controller, vnid, [access_lport, network_lport], 1)

+

+        stats = get_stats(self, ofp.message.group_desc_stats_request())

+ 

+        verify_group_stats=(ofp.group_desc_stats_entry(

+    	                    group_type=msg.group_type,

+						    group_id=msg.group_id,

+						    buckets=msg.buckets))

+

+        self.assertEquals(stats, [verify_group_stats])

+        #clear all group

+        delete_all_groups(self.controller)

+		#exit verification so clear all configuration

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+		                                        lport=access_lport, phy_port=access_phy_port, 

+												vlan=access_port_vid, vnid=vnid, operation="delete")

+        assert(send_edit_config(config["switch_ip"], vtap_conf_xml) == True)

+        vtep_conf_xml=get_vtep_lport_config_xml(dp_id=feature_reply.datapath_id, 

+		                                        lport=network_lport, 

+												src_ip=network_port_sip, dst_ip=network_port_dip, 

+												next_hop_id=next_hop_id, 

+												vnid=vnid, operation="delete")												

+        assert(send_edit_config(config["switch_ip"], vtep_conf_xml) == True)

+

+        vni_config_xml=get_vni_config_xml(vni_id=vnid, mcast_ipv4=None, next_hop_id=None, operation="delete")

+        assert(send_edit_config(config["switch_ip"], vni_config_xml) == True)

+

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id, 

+		                                          dst_mac=dst_mac, 

+												  phy_port=network_port_phy_port, 

+												  vlan=network_port_vlan, operation="delete")

+        assert(send_edit_config(config["switch_ip"], next_hop_conf_xml) == True)

+

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id_mcast, 

+		                                          dst_mac=dst_mac_mcast, 

+												  phy_port=network_port_phy_port, 

+												  vlan=network_port_vlan, operation="delete")

+        assert(send_edit_config(config["switch_ip"], next_hop_conf_xml) == True)            

+										        

+class AccessToNetworkDLFMcast(base_tests.SimpleDataPlane):

+    def runTest(self):

+        """

+        first verify flood over unicast, 

+        second verify flood over mcast

+        """

+        if 	config["switch_ip"] == None:

+            logging.error("Doesn't configure switch IP")		

+            return

+			

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+  

+        access_port1_vid=1

+        access_phy_port1=config["port_map"].keys()[0]

+        access_lport1=0x10001

+        access_port2_vid=0

+        access_phy_port2=config["port_map"].keys()[1]

+        access_lport2=0x10002

+        vnid=10

+        next_hop_id=1

+        next_hop_id_mcast=2

+        dst_mac="00:00:11:22:22:11"

+        mcast_ipv4="224.1.1.1"

+        dst_mac_mcast="01:00:5e:01:01:01"

+        network_port_phy_port=config["port_map"].keys()[2]

+        network_lport=0x10003

+        network_port_vlan=2

+        network_port_sip="192.168.1.1"

+        network_port_dip="192.168.2.1"

+

+        feature_reply=get_featureReplay(self)	

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id, 

+		                                          dst_mac=dst_mac, 

+												  phy_port=network_port_phy_port, 

+												  vlan=network_port_vlan)        

+        logging.info("config NextHop %d, DST_MAC %s, PHY %d, VLAN %d", next_hop_id, dst_mac, network_port_phy_port, network_port_vlan);

+        assert(send_edit_config(config["switch_ip"], next_hop_conf_xml)==True)

+        

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id_mcast, 

+		                                          dst_mac=dst_mac_mcast, 

+												  phy_port=network_port_phy_port, 

+												  vlan=network_port_vlan)        

+        logging.info("config NextHop %d, DST_MAC %s, PHY %d, VLAN %d", next_hop_id, dst_mac, network_port_phy_port, network_port_vlan);

+        assert(send_edit_config(config["switch_ip"], next_hop_conf_xml)==True)

+        

+        vni_config_xml=get_vni_config_xml(vni_id=vnid, mcast_ipv4=mcast_ipv4, next_hop_id=next_hop_id_mcast)

+        logging.info("config VNI %lx", vnid);

+        assert(send_edit_config(config["switch_ip"], vni_config_xml) == True)

+            

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                        lport=access_lport1, phy_port=access_phy_port1, 

+                                        vlan=access_port1_vid, vnid=vnid)

+        logging.info("config VTAP 0x%lx, PHY %d, VID %d, VNID %lx", access_lport1, access_phy_port1, access_port1_vid, vnid);

+        assert(send_edit_config(config["switch_ip"], vtap_conf_xml) == True)

+

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                        lport=access_lport2, phy_port=access_phy_port2, 

+                                        vlan=access_port2_vid, vnid=vnid)

+        logging.info("config VTAP 0x%lx, PHY %d, VID %d, VNID %lx", access_lport2, access_phy_port2, access_port2_vid, vnid);

+        assert(send_edit_config(config["switch_ip"], vtap_conf_xml) == True)            

+        vtep_conf_xml=get_vtep_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                                lport=network_lport, 

+                                                src_ip=network_port_sip, dst_ip=network_port_dip,

+                                                next_hop_id=next_hop_id, 

+                                                vnid=vnid)												

+        logging.info("config VTEP 0x%lx, SRC_IP %s, DST_IP %s, NEXTHOP_ID %d", network_lport, network_port_sip, network_port_dip, next_hop_id);                                                

+        assert(send_edit_config(config["switch_ip"], vtep_conf_xml) == True)

+

+        #get_edit_config(config["switch_ip"])

+        

+        #add port table to have vxlan ability

+        add_port_table_flow(self.controller)

+

+        #for network port need l2 interface group to decide vlan tag or not

+        add_one_l2_interface_group(self.controller, network_port_phy_port, vlan_id=network_port_vlan)

+

+		#add DLF bridge flow

+        msg=add_l2_overlay_flood_over_mcast_tunnel_group(self.controller, vnid, [access_lport1, access_lport2, network_lport], 1)        

+        add_overlay_bridge_flow(self.controller, None, vnid, msg.group_id, True, True)

+        

+        #send packet on access port

+        parsed_pkt = simple_udp_packet(pktlen=96, eth_dst='00:00:11:11:11:11',

+                                       dl_vlan_enable= True,

+                                       vlan_vid=access_port1_vid)

+        pkt = str(parsed_pkt)

+        self.dataplane.send(access_phy_port1, pkt)

+

+        #verify packet on access port		

+        parsed_pkt = simple_udp_packet(pktlen=92, eth_dst='00:00:11:11:11:11')

+        pkt = str(parsed_pkt) 

+        verify_packet(self, pkt, access_phy_port2)

+        #vxlan packet IP header have some parmater decide by HW,

+        #we can easy to check VxLAN IP header

+        verify_packet(self, pkt, network_port_phy_port)        

+        verify_no_other_packets(self)

+

+        add_overlay_bridge_flow(self.controller, [0x00, 0x12, 0x34, 0x56, 0x78, 0x9a], vnid, network_lport, False, True)        

+        parsed_pkt = simple_udp_packet(pktlen=96, eth_dst='00:12:34:56:78:9a',

+                                       dl_vlan_enable= True,

+                                       vlan_vid=access_port1_vid)

+        pkt = str(parsed_pkt)

+        self.dataplane.send(access_phy_port1, pkt)

+        #verify packet on network port		

+        parsed_pkt = simple_udp_packet(pktlen=92, eth_dst='00:12:34:56:78:9a')

+        pkt = str(parsed_pkt) 

+        verify_packet(self, pkt, network_port_phy_port)        

+        verify_no_other_packets(self)

+        

+		#exit verification so clear all configuration

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+		                                        lport=access_lport1, phy_port=access_phy_port1, 

+												vlan=access_port1_vid, vnid=vnid, operation="delete")

+        assert(send_edit_config(config["switch_ip"], vtap_conf_xml) == True)

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+		                                        lport=access_lport2, phy_port=access_phy_port2, 

+												vlan=access_port2_vid, vnid=vnid, operation="delete")

+        assert(send_edit_config(config["switch_ip"], vtap_conf_xml) == True)            

+        vtep_conf_xml=get_vtep_lport_config_xml(dp_id=feature_reply.datapath_id, 

+		                                        lport=network_lport, 

+												src_ip=network_port_sip, dst_ip=network_port_dip, 

+												next_hop_id=next_hop_id, 

+												vnid=vnid, operation="delete")												

+        assert(send_edit_config(config["switch_ip"], vtep_conf_xml) == True)

+        

+        vni_config_xml=get_vni_config_xml(vni_id=vnid, mcast_ipv4=None, next_hop_id=None, operation="delete")

+        assert(send_edit_config(config["switch_ip"], vni_config_xml) == True)

+        

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id, 

+		                                          dst_mac=dst_mac, 

+												  phy_port=network_port_phy_port, 

+												  vlan=network_port_vlan, operation="delete")

+        assert(send_edit_config(config["switch_ip"], next_hop_conf_xml) == True)

+        

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id_mcast, 

+		                                          dst_mac=dst_mac_mcast, 

+												  phy_port=network_port_phy_port, 

+												  vlan=network_port_vlan, operation="delete")

+        assert(send_edit_config(config["switch_ip"], next_hop_conf_xml) == True)

+

+class AccessToNetworkDLFUcast(base_tests.SimpleDataPlane):

+    def runTest(self):

+        """

+        first verify flood over unicast, 

+        second verify flood over mcast

+        """

+        if 	config["switch_ip"] == None:

+            logging.error("Doesn't configure switch IP")		

+            return

+			

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+  

+        access_port1_vid=1

+        access_phy_port1=config["port_map"].keys()[0]

+        access_lport1=0x10001

+        access_port2_vid=0

+        access_phy_port2=config["port_map"].keys()[1]

+        access_lport2=0x10002

+        vnid=10

+        next_hop_id=1

+        next_hop_id_mcast=2

+        dst_mac="00:00:11:22:22:11"

+        mcast_ipv4="224.1.1.1"

+        dst_mac_mcast="01:00:5e:01:01:01"

+        network_port_phy_port=config["port_map"].keys()[2]

+        network_lport=0x10003

+        network_port_vlan=2

+        network_port_sip="192.168.1.1"

+        network_port_dip="192.168.2.1"

+

+        feature_reply=get_featureReplay(self)	

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id, 

+		                                          dst_mac=dst_mac, 

+												  phy_port=network_port_phy_port, 

+												  vlan=network_port_vlan)        

+        logging.info("config NextHop %d, DST_MAC %s, PHY %d, VLAN %d", next_hop_id, dst_mac, network_port_phy_port, network_port_vlan);

+        assert(send_edit_config(config["switch_ip"], next_hop_conf_xml)==True)

+        

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id_mcast, 

+		                                          dst_mac=dst_mac_mcast, 

+												  phy_port=network_port_phy_port, 

+												  vlan=network_port_vlan)        

+        logging.info("config NextHop %d, DST_MAC %s, PHY %d, VLAN %d", next_hop_id, dst_mac, network_port_phy_port, network_port_vlan);

+        assert(send_edit_config(config["switch_ip"], next_hop_conf_xml)==True)

+        

+        vni_config_xml=get_vni_config_xml(vni_id=vnid, mcast_ipv4=mcast_ipv4, next_hop_id=next_hop_id_mcast)

+        logging.info("config VNI %lx", vnid);

+        assert(send_edit_config(config["switch_ip"], vni_config_xml) == True)

+            

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                        lport=access_lport1, phy_port=access_phy_port1, 

+                                        vlan=access_port1_vid, vnid=vnid)

+        logging.info("config VTAP 0x%lx, PHY %d, VID %d, VNID %lx", access_lport1, access_phy_port1, access_port1_vid, vnid);

+        assert(send_edit_config(config["switch_ip"], vtap_conf_xml) == True)

+

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                        lport=access_lport2, phy_port=access_phy_port2, 

+                                        vlan=access_port2_vid, vnid=vnid)

+        logging.info("config VTAP 0x%lx, PHY %d, VID %d, VNID %lx", access_lport2, access_phy_port2, access_port2_vid, vnid);

+        assert(send_edit_config(config["switch_ip"], vtap_conf_xml) == True)            

+        vtep_conf_xml=get_vtep_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                                lport=network_lport, 

+                                                src_ip=network_port_sip, dst_ip=network_port_dip,

+                                                next_hop_id=next_hop_id, 

+                                                vnid=vnid)												

+        logging.info("config VTEP 0x%lx, SRC_IP %s, DST_IP %s, NEXTHOP_ID %d", network_lport, network_port_sip, network_port_dip, next_hop_id);                                                

+        assert(send_edit_config(config["switch_ip"], vtep_conf_xml) == True)

+

+        #get_edit_config(config["switch_ip"])

+        

+        #add port table to have vxlan ability

+        add_port_table_flow(self.controller)

+

+        #for network port need l2 interface group to decide vlan tag or not

+        add_one_l2_interface_group(self.controller, network_port_phy_port, vlan_id=network_port_vlan)

+

+		#add DLF bridge flow

+        msg=add_l2_overlay_flood_over_unicast_tunnel_group(self.controller, vnid, [access_lport1, access_lport2, network_lport], 1)        

+        add_overlay_bridge_flow(self.controller, None, vnid, msg.group_id, True, True)

+        

+        #send packet on access port

+        parsed_pkt = simple_udp_packet(pktlen=96, eth_dst='00:00:11:11:11:11',

+                                       dl_vlan_enable= True,

+                                       vlan_vid=access_port1_vid)

+        pkt = str(parsed_pkt)

+        self.dataplane.send(access_phy_port1, pkt)

+

+        #verify packet on access port		

+        parsed_pkt = simple_udp_packet(pktlen=92, eth_dst='00:00:11:11:11:11')

+        pkt = str(parsed_pkt) 

+        verify_packet(self, pkt, access_phy_port2)

+        #vxlan packet IP header have some parmater decide by HW,

+        #we can easy to check VxLAN IP header

+        verify_packet(self, pkt, network_port_phy_port)        

+        verify_no_other_packets(self)

+

+        add_overlay_bridge_flow(self.controller, [0x00, 0x12, 0x34, 0x56, 0x78, 0x9a], vnid, network_lport, False, True)        

+        parsed_pkt = simple_udp_packet(pktlen=96, eth_dst='00:12:34:56:78:9a',

+                                       dl_vlan_enable= True,

+                                       vlan_vid=access_port1_vid)

+        pkt = str(parsed_pkt)

+        self.dataplane.send(access_phy_port1, pkt)

+        #verify packet on network port		

+        parsed_pkt = simple_udp_packet(pktlen=92, eth_dst='00:12:34:56:78:9a')

+        pkt = str(parsed_pkt) 

+        verify_packet(self, pkt, network_port_phy_port)        

+        verify_no_other_packets(self)

+        

+		#exit verification so clear all configuration

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+		                                        lport=access_lport1, phy_port=access_phy_port1, 

+												vlan=access_port1_vid, vnid=vnid, operation="delete")

+        assert(send_edit_config(config["switch_ip"], vtap_conf_xml) == True)

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+		                                        lport=access_lport2, phy_port=access_phy_port2, 

+												vlan=access_port2_vid, vnid=vnid, operation="delete")

+        assert(send_edit_config(config["switch_ip"], vtap_conf_xml) == True)            

+        vtep_conf_xml=get_vtep_lport_config_xml(dp_id=feature_reply.datapath_id, 

+		                                        lport=network_lport, 

+												src_ip=network_port_sip, dst_ip=network_port_dip, 

+												next_hop_id=next_hop_id, 

+												vnid=vnid, operation="delete")												

+        assert(send_edit_config(config["switch_ip"], vtep_conf_xml) == True)

+        

+        vni_config_xml=get_vni_config_xml(vni_id=vnid, mcast_ipv4=None, next_hop_id=None, operation="delete")

+        assert(send_edit_config(config["switch_ip"], vni_config_xml) == True)

+        

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id, 

+		                                          dst_mac=dst_mac, 

+												  phy_port=network_port_phy_port, 

+												  vlan=network_port_vlan, operation="delete")

+        assert(send_edit_config(config["switch_ip"], next_hop_conf_xml) == True)

+        

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id_mcast, 

+		                                          dst_mac=dst_mac_mcast, 

+												  phy_port=network_port_phy_port, 

+												  vlan=network_port_vlan, operation="delete")

+        assert(send_edit_config(config["switch_ip"], next_hop_conf_xml) == True)

+

+class AccessWithAccessDiffPortVlan(base_tests.SimpleDataPlane):

+   def runTest(self):

+        """

+        first verify flood over unicast, 

+        second verify flood over mcast

+        """

+        if 	config["switch_ip"] == None:

+            logging.error("Doesn't configure switch IP")		

+            return

+			

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+  

+        access_port1_vid=1

+        access_phy_port1=config["port_map"].keys()[0]

+        access_lport1=0x10001

+        access_port2_vid=0

+        access_phy_port2=config["port_map"].keys()[1]

+        access_lport2=0x10002

+        access_port3_vid=3

+        access_phy_port3=config["port_map"].keys()[2]

+        access_lport3=0x10003

+        vnid=10

+        next_hop_id_mcast=1

+        mcast_ipv4="224.1.1.1"

+        dst_mac_mcast="01:00:5e:01:01:01"

+        

+        feature_reply=get_featureReplay(self)	

+        

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id_mcast, 

+		                                          dst_mac=dst_mac_mcast, 

+												  phy_port=access_phy_port3, 

+												  vlan=access_port3_vid)        

+        logging.info("config NextHop %d, DST_MAC %s, PHY %d, VLAN %d", next_hop_id_mcast, dst_mac_mcast, access_phy_port3, access_port3_vid);

+        assert(send_edit_config(config["switch_ip"], next_hop_conf_xml)==True)

+

+        vni_config_xml=get_vni_config_xml(vni_id=vnid, mcast_ipv4=mcast_ipv4, next_hop_id=next_hop_id_mcast)

+        logging.info("config VNI %lx", vnid);

+        assert(send_edit_config(config["switch_ip"], vni_config_xml) == True)

+            

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                        lport=access_lport1, phy_port=access_phy_port1, 

+                                        vlan=access_port1_vid, vnid=vnid)

+        logging.info("config VTAP 0x%lx, PHY %d, VID %d, VNID %lx", access_lport1, access_phy_port1, access_port1_vid, vnid);

+        assert(send_edit_config(config["switch_ip"], vtap_conf_xml) == True)

+

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                        lport=access_lport2, phy_port=access_phy_port2, 

+                                        vlan=access_port2_vid, vnid=vnid)

+        logging.info("config VTAP 0x%lx, PHY %d, VID %d, VNID %lx", access_lport2, access_phy_port2, access_port2_vid, vnid);

+        assert(send_edit_config(config["switch_ip"], vtap_conf_xml) == True)            

+        

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                        lport=access_lport3, phy_port=access_phy_port3, 

+                                        vlan=access_port3_vid, vnid=vnid)

+        logging.info("config VTAP 0x%lx, PHY %d, VID %d, VNID %lx", access_lport3, access_phy_port3, access_port3_vid, vnid);

+        assert(send_edit_config(config["switch_ip"], vtap_conf_xml) == True)            

+

+        

+        #add port table to have vxlan ability

+        add_port_table_flow(self.controller)

+

+		#add DLF bridge flow

+        msg=add_l2_overlay_flood_over_mcast_tunnel_group(self.controller, vnid, [access_lport1, access_lport2, access_lport3], 1)        

+        add_overlay_bridge_flow(self.controller, None, vnid, msg.group_id, True, True)

+        

+        #send packet on access port

+        parsed_pkt = simple_udp_packet(pktlen=96, eth_dst='00:00:11:11:11:11',

+                                       dl_vlan_enable= True,

+                                       vlan_vid=access_port1_vid)

+        pkt = str(parsed_pkt)

+        self.dataplane.send(access_phy_port1, pkt)

+

+        #verify packet on access port 2, vid=0, so untag

+        parsed_pkt = simple_udp_packet(pktlen=92, eth_dst='00:00:11:11:11:11')

+        pkt = str(parsed_pkt) 

+        verify_packet(self, pkt, access_phy_port2)

+        #verify packet on access port 3

+        parsed_pkt = simple_udp_packet(pktlen=96, eth_dst='00:00:11:11:11:11',

+                                       dl_vlan_enable= True,

+                                       vlan_vid=access_port3_vid)

+        pkt = str(parsed_pkt)

+        verify_packet(self, pkt, access_phy_port3) 

+        verify_no_other_packets(self)

+        

+        add_overlay_bridge_flow(self.controller, [0x00, 0x12, 0x34, 0x56, 0x78, 0x9a], vnid, access_lport2, False, True)        

+        parsed_pkt = simple_udp_packet(pktlen=96, eth_dst='00:12:34:56:78:9a',

+                                       dl_vlan_enable= True,

+                                       vlan_vid=access_port1_vid)

+        pkt = str(parsed_pkt)

+        self.dataplane.send(access_phy_port1, pkt)

+        #verify packet on access port		

+        parsed_pkt = simple_udp_packet(pktlen=92, eth_dst='00:12:34:56:78:9a')

+        pkt = str(parsed_pkt) 

+        verify_packet(self, pkt, access_phy_port2)        

+        verify_no_other_packets(self)

+

+

+        add_overlay_bridge_flow(self.controller, [0x00, 0x12, 0x34, 0x56, 0x78, 0xaa], vnid, access_lport3, False, True)

+        parsed_pkt = simple_udp_packet(pktlen=96, eth_dst='00:12:34:56:78:aa',

+                                       dl_vlan_enable= True,

+                                       vlan_vid=access_port1_vid)

+        pkt = str(parsed_pkt)

+        self.dataplane.send(access_phy_port1, pkt)

+        #verify packet on access port		

+        parsed_pkt = simple_udp_packet(pktlen=96, eth_dst='00:12:34:56:78:aa',

+                                       dl_vlan_enable= True,

+                                       vlan_vid=access_port3_vid)

+        pkt = str(parsed_pkt) 

+        verify_packet(self, pkt, access_phy_port3)

+        verify_no_other_packets(self)

+

+        

+        

+		#exit verification so clear all configuration

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+		                                        lport=access_lport1, phy_port=access_phy_port1, 

+												vlan=access_port1_vid, vnid=vnid, operation="delete")

+        assert(send_edit_config(config["switch_ip"], vtap_conf_xml) == True)

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+		                                        lport=access_lport2, phy_port=access_phy_port2, 

+												vlan=access_port2_vid, vnid=vnid, operation="delete")

+        assert(send_edit_config(config["switch_ip"], vtap_conf_xml) == True)            

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                        lport=access_lport3, phy_port=access_phy_port3, 

+                                        vlan=access_port3_vid, vnid=vnid, operation="delete")

+        logging.info("config VTAP 0x%lx, PHY %d, VID %d, VNID %lx", access_lport3, access_phy_port3, access_port3_vid, vnid);

+        assert(send_edit_config(config["switch_ip"], vtap_conf_xml) == True)   

+        

+        vni_config_xml=get_vni_config_xml(vni_id=vnid, mcast_ipv4=None, next_hop_id=None, operation="delete")

+        assert(send_edit_config(config["switch_ip"], vni_config_xml) == True)

+

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id_mcast, 

+		                                          dst_mac=dst_mac_mcast, 

+												  phy_port=access_phy_port3, 

+												  vlan=access_port3_vid, operation="delete")

+        assert(send_edit_config(config["switch_ip"], next_hop_conf_xml) == True)

+

+        

+class AccessWithAccessSamePortDiffVlan(base_tests.SimpleDataPlane):

+   def runTest(self):

+        """

+        first verify flood over unicast, 

+        second verify flood over mcast

+        """

+        if 	config["switch_ip"] == None:

+            logging.error("Doesn't configure switch IP")		

+            return

+			

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+  

+        access_port1_vid=1

+        access_phy_port1=config["port_map"].keys()[0]

+        access_lport1=0x10001

+        access_port2_vid=2

+        access_phy_port2= access_phy_port1

+        access_lport2=0x10002

+        access_port3_vid=3

+        access_phy_port3=access_phy_port1

+        access_lport3=0x10003

+        vnid=10

+        next_hop_id_mcast=1

+        mcast_ipv4="224.1.1.1"

+        dst_mac_mcast="01:00:5e:01:01:01"

+        

+        feature_reply=get_featureReplay(self)	

+        

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id_mcast, 

+		                                          dst_mac=dst_mac_mcast, 

+												  phy_port=access_phy_port3, 

+												  vlan=access_port3_vid)        

+        logging.info("config NextHop %d, DST_MAC %s, PHY %d, VLAN %d", next_hop_id_mcast, dst_mac_mcast, access_phy_port3, access_port3_vid);

+        assert(send_edit_config(config["switch_ip"], next_hop_conf_xml)==True)

+

+        vni_config_xml=get_vni_config_xml(vni_id=vnid, mcast_ipv4=mcast_ipv4, next_hop_id=next_hop_id_mcast)

+        logging.info("config VNI %lx", vnid);

+        assert(send_edit_config(config["switch_ip"], vni_config_xml) == True)

+            

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                        lport=access_lport1, phy_port=access_phy_port1, 

+                                        vlan=access_port1_vid, vnid=vnid)

+        logging.info("config VTAP 0x%lx, PHY %d, VID %d, VNID %lx", access_lport1, access_phy_port1, access_port1_vid, vnid);

+        assert(send_edit_config(config["switch_ip"], vtap_conf_xml) == True)

+

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                        lport=access_lport2, phy_port=access_phy_port2, 

+                                        vlan=access_port2_vid, vnid=vnid)

+        logging.info("config VTAP 0x%lx, PHY %d, VID %d, VNID %lx", access_lport2, access_phy_port2, access_port2_vid, vnid);

+        assert(send_edit_config(config["switch_ip"], vtap_conf_xml) == True)            

+        

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                        lport=access_lport3, phy_port=access_phy_port3, 

+                                        vlan=access_port3_vid, vnid=vnid)

+        logging.info("config VTAP 0x%lx, PHY %d, VID %d, VNID %lx", access_lport3, access_phy_port3, access_port3_vid, vnid);

+        assert(send_edit_config(config["switch_ip"], vtap_conf_xml) == True)            

+

+        

+        #add port table to have vxlan ability

+        add_port_table_flow(self.controller)

+

+		#add DLF bridge flow

+        msg=add_l2_overlay_flood_over_mcast_tunnel_group(self.controller, vnid, [access_lport1, access_lport2, access_lport3], 1)        

+        add_overlay_bridge_flow(self.controller, None, vnid, msg.group_id, True, True)

+        

+        #send packet on access port

+        parsed_pkt = simple_udp_packet(pktlen=96, eth_dst='00:00:11:11:11:11',

+                                       dl_vlan_enable= True,

+                                       vlan_vid=access_port1_vid)

+        pkt = str(parsed_pkt)

+        self.dataplane.send(access_phy_port1, pkt)

+

+        #verify packet on access port 2, vid=0, so untag

+        parsed_pkt = simple_udp_packet(pktlen=96, eth_dst='00:00:11:11:11:11',

+                                       dl_vlan_enable = True,

+                                       vlan_vid = access_port2_vid)

+        pkt = str(parsed_pkt) 

+        verify_packet(self, pkt, access_phy_port2)

+        #verify packet on access port 3

+        parsed_pkt = simple_udp_packet(pktlen=96, eth_dst='00:00:11:11:11:11',

+                                       dl_vlan_enable= True,

+                                       vlan_vid=access_port3_vid)

+        pkt = str(parsed_pkt)

+        verify_packet(self, pkt, access_phy_port3) 

+        verify_no_other_packets(self)

+        

+        add_overlay_bridge_flow(self.controller, [0x00, 0x12, 0x34, 0x56, 0x78, 0x9a], vnid, access_lport2, False, True)        

+        parsed_pkt = simple_udp_packet(pktlen=96, eth_dst='00:12:34:56:78:9a',

+                                       dl_vlan_enable= True,

+                                       vlan_vid=access_port1_vid)

+        pkt = str(parsed_pkt)

+        self.dataplane.send(access_phy_port1, pkt)

+        #verify packet on access port		

+        parsed_pkt = simple_udp_packet(pktlen=96, eth_dst='00:12:34:56:78:9a',

+                                       dl_vlan_enable = True,

+                                       vlan_vid = access_port2_vid)

+        pkt = str(parsed_pkt) 

+        verify_packet(self, pkt, access_phy_port2)        

+        verify_no_other_packets(self)

+

+

+        add_overlay_bridge_flow(self.controller, [0x00, 0x12, 0x34, 0x56, 0x78, 0xaa], vnid, access_lport3, False, True)

+        parsed_pkt = simple_udp_packet(pktlen=96, eth_dst='00:12:34:56:78:aa',

+                                       dl_vlan_enable= True,

+                                       vlan_vid=access_port1_vid)

+        pkt = str(parsed_pkt)

+        self.dataplane.send(access_phy_port1, pkt)

+        #verify packet on access port		

+        parsed_pkt = simple_udp_packet(pktlen=96, eth_dst='00:12:34:56:78:aa',

+                                       dl_vlan_enable= True,

+                                       vlan_vid=access_port3_vid)

+        pkt = str(parsed_pkt) 

+        verify_packet(self, pkt, access_phy_port3)

+        verify_no_other_packets(self)

+

+        add_overlay_bridge_flow(self.controller, [0x00, 0x12, 0x34, 0x56, 0x78, 0xbb], vnid, access_lport2, False, True)

+        parsed_pkt = simple_udp_packet(pktlen=96, eth_dst='00:12:34:56:78:bb',

+                                       dl_vlan_enable= True,

+                                       vlan_vid=access_port1_vid)

+        pkt = str(parsed_pkt)

+        self.dataplane.send(access_phy_port1, pkt)

+        #verify packet on access port		

+        parsed_pkt = simple_udp_packet(pktlen=96, eth_dst='00:12:34:56:78:bb',

+                                       dl_vlan_enable= True,

+                                       vlan_vid=access_port2_vid)

+        pkt = str(parsed_pkt) 

+        verify_packet(self, pkt, access_phy_port2)

+        verify_no_other_packets(self)        

+        

+		#exit verification so clear all configuration

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+		                                        lport=access_lport1, phy_port=access_phy_port1, 

+												vlan=access_port1_vid, vnid=vnid, operation="delete")

+        assert(send_edit_config(config["switch_ip"], vtap_conf_xml) == True)

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+		                                        lport=access_lport2, phy_port=access_phy_port2, 

+												vlan=access_port2_vid, vnid=vnid, operation="delete")

+        assert(send_edit_config(config["switch_ip"], vtap_conf_xml) == True)            

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                        lport=access_lport3, phy_port=access_phy_port3, 

+                                        vlan=access_port3_vid, vnid=vnid, operation="delete")

+        logging.info("config VTAP 0x%lx, PHY %d, VID %d, VNID %lx", access_lport3, access_phy_port3, access_port3_vid, vnid);

+        assert(send_edit_config(config["switch_ip"], vtap_conf_xml) == True)   

+        

+        vni_config_xml=get_vni_config_xml(vni_id=vnid, mcast_ipv4=None, next_hop_id=None, operation="delete")

+        assert(send_edit_config(config["switch_ip"], vni_config_xml) == True)

+

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id_mcast, 

+		                                          dst_mac=dst_mac_mcast, 

+												  phy_port=access_phy_port3, 

+												  vlan=access_port3_vid, operation="delete")

+        assert(send_edit_config(config["switch_ip"], next_hop_conf_xml) == True)

+

+        

+class AccessWithNetwork(base_tests.SimpleDataPlane):

+    def runTest(self):

+        """

+        first verify flood over unicast, 

+        second verify flood over mcast

+        """

+        if 	config["switch_ip"] == None:

+            logging.error("Doesn't configure switch IP")		

+            return

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        access_port1_vid=1

+        access_phy_port1=config["port_map"].keys()[0]

+        access_lport1=0x10001

+        access_lport1_mac=[0x00, 0x00, 0x00, 0x77, 0x77, 0x77]

+        access_lport1_mac_str=(":".join(map(str, map(hex, access_lport1_mac)))).replace("0x", "")

+        access_port2_vid=0

+        access_phy_port2=config["port_map"].keys()[1]

+        access_lport2=0x10002

+        access_lport2_mac=[0x00,0x00, 0x00, 0x00, 0x00, 0x02]

+        access_lport2_mac_str=(":".join(map(str, map(hex, access_lport2_mac)))).replace("0x", "")		

+        vnid=10

+        next_hop_id=1

+        next_hop_id_mcast=2

+        dst_mac="00:00:11:22:22:11"

+        mcast_ipv4="224.1.1.1"

+        dst_mac_mcast="01:00:5e:01:01:01"

+        network_port_phy_port=config["port_map"].keys()[2]

+        network_lport=0x10003

+        network_port_vlan=2

+        network_port_sip="192.168.1.1"

+        network_port_dip="192.168.2.1"

+        network_lport_mac=[0x00,0x00, 0x00, 0x00, 0x00, 0x03]

+        network_lport_mac_str=(":".join(map(str, map(hex, network_lport_mac)))).replace("0x", "")

+

+

+        

+        feature_reply=get_featureReplay(self)	

+        #get switch CPU mac

+        str_datapath_id_f= "{:016x}".format(feature_reply.datapath_id)        

+        str_datapath_id=':'.join([str_datapath_id_f[i:i+2] for i in range(0, len(str_datapath_id_f), 2)])        

+        switch_cpu_mac_str=str_datapath_id[6:]

+        switch_cpu_mac = switch_cpu_mac_str.split(":")

+        switch_cpu_mac=[int(switch_cpu_mac[i],16) for i in range(0, len(switch_cpu_mac))]

+

+        #add config vtep/vtap/nexthop/vni        

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id, 

+		                                          dst_mac=dst_mac, 

+												  phy_port=network_port_phy_port, 

+												  vlan=network_port_vlan)        

+        logging.info("config NextHop %d, DST_MAC %s, PHY %d, VLAN %d", next_hop_id, dst_mac, network_port_phy_port, network_port_vlan);

+        assert(send_edit_config(config["switch_ip"], next_hop_conf_xml)==True)

+

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id_mcast, 

+		                                          dst_mac=dst_mac_mcast, 

+												  phy_port=network_port_phy_port, 

+												  vlan=network_port_vlan)        

+        logging.info("config NextHop %d, DST_MAC %s, PHY %d, VLAN %d", next_hop_id, dst_mac, network_port_phy_port, network_port_vlan);

+

+        assert(send_edit_config(config["switch_ip"], next_hop_conf_xml)==True)

+        

+        vni_config_xml=get_vni_config_xml(vni_id=vnid, mcast_ipv4=mcast_ipv4, next_hop_id=next_hop_id_mcast)

+        #vni_config_xml=get_vni_config_xml(vni_id=vnid, mcast_ipv4=None, next_hop_id=None)

+        logging.info("config VNI %lx", vnid);

+        assert(send_edit_config(config["switch_ip"], vni_config_xml) == True)

+            

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                        lport=access_lport1, phy_port=access_phy_port1, 

+                                        vlan=access_port1_vid, vnid=vnid)

+        logging.info("config VTAP 0x%lx, PHY %d, VID %d, VNID %lx", access_lport1, access_phy_port1, access_port1_vid, vnid);

+        assert(send_edit_config(config["switch_ip"], vtap_conf_xml) == True)

+

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                        lport=access_lport2, phy_port=access_phy_port2, 

+                                        vlan=access_port2_vid, vnid=vnid)

+        logging.info("config VTAP 0x%lx, PHY %d, VID %d, VNID %lx", access_lport2, access_phy_port2, access_port2_vid, vnid);

+        assert(send_edit_config(config["switch_ip"], vtap_conf_xml) == True)            

+        vtep_conf_xml=get_vtep_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                                lport=network_lport, 

+                                                src_ip=network_port_sip, dst_ip=network_port_dip,

+                                                next_hop_id=next_hop_id, 

+                                                vnid=vnid)												

+        logging.info("config VTEP 0x%lx, SRC_IP %s, DST_IP %s, NEXTHOP_ID %d", network_lport, network_port_sip, network_port_dip, next_hop_id);                                                

+        assert(send_edit_config(config["switch_ip"], vtep_conf_xml) == True)

+

+        #add port table to have vxlan ability

+        add_port_table_flow(self.controller)

+        add_port_table_flow(self.controller, is_overlay=False)

+        

+        #for network port need l2 interface group to decide vlan tag or not

+        add_one_l2_interface_group(self.controller, network_port_phy_port, vlan_id=network_port_vlan)

+        #add network mac

+        add_overlay_bridge_flow(self.controller, network_lport_mac, vnid, network_lport, False, True)

+        add_overlay_bridge_flow(self.controller, access_lport1_mac, vnid, access_lport1, False, True)

+

+        #add termination table for network port

+        add_termination_flow(self.controller, in_port=network_port_phy_port, eth_type=0x0800,

+                             dst_mac=switch_cpu_mac, vlanid=network_port_vlan)

+        #add vlan table for network port rx packet class vlan

+        add_one_vlan_table_flow(self.controller, of_port=network_port_phy_port, 

+                                vlan_id=network_port_vlan)

+

+        #tx packet on access lport 1        

+        parsed_pkt = simple_udp_packet(pktlen=96, eth_dst=network_lport_mac_str,

+                                       dl_vlan_enable= True,

+                                       vlan_vid=access_port1_vid)

+        pkt = str(parsed_pkt)

+        self.dataplane.send(access_phy_port1, pkt)

+        #verify packet on network port	

+        #need find a way to verify vxlan header        

+        parsed_pkt = simple_udp_packet(pktlen=92, eth_dst=network_lport_mac_str)

+        pkt = str(parsed_pkt) 

+        verify_packet(self, pkt, network_port_phy_port)        

+        verify_no_other_packets(self)

+        

+        #tx packet on network lport

+        inner_pkt = simple_udp_packet(pktlen=96, eth_dst=access_lport1_mac_str)

+        vxlan_pkt = simple_vxlan_packet(eth_dst=switch_cpu_mac_str,

+                                        vnid=vnid, 

+                                        ip_dst= network_port_sip, 

+                                        ip_src=network_port_dip,

+                                        inner_payload=inner_pkt)

+        self.dataplane.send(network_port_phy_port, str(vxlan_pkt))

+        #verify

+        inner_pkt = simple_udp_packet(pktlen=100, eth_dst=access_lport1_mac_str,

+                                       dl_vlan_enable= True,

+                                       vlan_vid=access_port1_vid)

+        

+        verify_packet(self, inner_pkt, access_phy_port1)

+        verify_no_other_packets(self)

+

+

+		#exit verification so clear all configuration

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+		                                        lport=access_lport1, phy_port=access_phy_port1, 

+												vlan=access_port1_vid, vnid=vnid, operation="delete")

+        assert(send_edit_config(config["switch_ip"], vtap_conf_xml) == True)

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+		                                        lport=access_lport2, phy_port=access_phy_port2, 

+												vlan=access_port2_vid, vnid=vnid, operation="delete")

+        assert(send_edit_config(config["switch_ip"], vtap_conf_xml) == True)            

+        vtep_conf_xml=get_vtep_lport_config_xml(dp_id=feature_reply.datapath_id, 

+		                                        lport=network_lport, 

+												src_ip=network_port_sip, dst_ip=network_port_dip, 

+												next_hop_id=next_hop_id, 

+												vnid=vnid, operation="delete")												

+        assert(send_edit_config(config["switch_ip"], vtep_conf_xml) == True)

+        

+        vni_config_xml=get_vni_config_xml(vni_id=vnid, mcast_ipv4=None, next_hop_id=None, operation="delete")

+        assert(send_edit_config(config["switch_ip"], vni_config_xml) == True)

+        

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id, 

+		                                          dst_mac=dst_mac, 

+												  phy_port=network_port_phy_port, 

+												  vlan=network_port_vlan, operation="delete")

+        assert(send_edit_config(config["switch_ip"], next_hop_conf_xml) == True)

+        

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id_mcast, 

+		                                          dst_mac=dst_mac_mcast, 

+												  phy_port=network_port_phy_port, 

+												  vlan=network_port_vlan, operation="delete")

+        assert(send_edit_config(config["switch_ip"], next_hop_conf_xml) == True)

+        

+class NetworkToNetwork(base_tests.SimpleDataPlane):

+    def runTest(self):

+        """

+        This case can't work, can't identify it is chip limitation or not

+        """

+        return

+        if 	config["switch_ip"] == None:

+            logging.error("Doesn't configure switch IP")		

+            return

+			

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+  

+        vnid=10

+        mcast_ipv4="224.1.1.1"

+        dst_mac_mcast="01:00:5e:01:01:01"       

+        next_hop_id_mcast=3

+

+        access_port1_vid=1

+        access_phy_port1=config["port_map"].keys()[0]

+        access_lport1=0x10001

+

+        network_port1_phy_port=config["port_map"].keys()[1]

+        network_lport1=0x10003

+        network_port1_vlan=2

+        network_port1_sip="192.168.1.1"

+        network_port1_dip="192.168.2.1"

+        network_port1_next_hop_id=1

+        network_port1_dst_mac="00:00:11:22:22:11"

+        network_lport1_mac=[0x00,0x00, 0x00, 0x00, 0x00, 0x33]

+        network_lport1_mac_str=(":".join(map(str, map(hex, network_lport1_mac)))).replace("0x", "")

+        

+        network_port2_phy_port=config["port_map"].keys()[2]

+        network_lport2=0x10004

+        network_port2_vlan=3

+        network_port2_sip="192.168.3.1"

+        network_port2_dip="192.168.4.1"

+        network_port2_next_hop_id=2

+        network_port2_dst_mac="00:00:11:22:22:22"

+        network_lport2_mac=[0x00,0x00, 0x00, 0x00, 0x00, 0x44]

+        network_lport2_mac_str=(":".join(map(str, map(hex, network_lport2_mac)))).replace("0x", "")

+        

+        feature_reply=get_featureReplay(self)	

+        #get switch CPU mac

+        str_datapath_id_f= "{:016x}".format(feature_reply.datapath_id)        

+        str_datapath_id=':'.join([str_datapath_id_f[i:i+2] for i in range(0, len(str_datapath_id_f), 2)])        

+        switch_cpu_mac_str=str_datapath_id[6:]

+        switch_cpu_mac = switch_cpu_mac_str.split(":")

+        switch_cpu_mac=[int(switch_cpu_mac[i],16) for i in range(0, len(switch_cpu_mac))]

+        #config vlxan

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=network_port1_next_hop_id, 

+		                                          dst_mac=network_port1_dst_mac, 

+												  phy_port=network_port1_phy_port, 

+												  vlan=network_port1_vlan)        

+        logging.info("config NextHop %d, DST_MAC %s, PHY %d, VLAN %d", network_port1_next_hop_id, network_port1_dst_mac, network_port1_phy_port, network_port1_vlan);

+        assert(send_edit_config(config["switch_ip"], next_hop_conf_xml)==True)

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=network_port2_next_hop_id, 

+		                                          dst_mac=network_port2_dst_mac, 

+												  phy_port=network_port2_phy_port, 

+												  vlan=network_port2_vlan)        

+        logging.info("config NextHop %d, DST_MAC %s, PHY %d, VLAN %d", network_port2_next_hop_id, network_port2_dst_mac, network_port2_phy_port, network_port2_vlan);

+        assert(send_edit_config(config["switch_ip"], next_hop_conf_xml)==True)

+        

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id_mcast, 

+		                                          dst_mac=dst_mac_mcast, 

+												  phy_port=network_port1_phy_port, 

+												  vlan=network_port1_vlan)        

+        logging.info("config NextHop %d, DST_MAC %s, PHY %d, VLAN %d", next_hop_id_mcast, dst_mac_mcast, network_port1_phy_port, network_port1_vlan);

+        assert(send_edit_config(config["switch_ip"], next_hop_conf_xml)==True)

+        

+        vni_config_xml=get_vni_config_xml(vni_id=vnid, mcast_ipv4=mcast_ipv4, next_hop_id=next_hop_id_mcast)

+        logging.info("config VNI %lx", vnid);

+        assert(send_edit_config(config["switch_ip"], vni_config_xml) == True)

+            

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                        lport=access_lport1, phy_port=access_phy_port1, 

+                                        vlan=access_port1_vid, vnid=vnid)

+        logging.info("config VTAP 0x%lx, PHY %d, VID %d, VNID %lx", access_lport1, access_phy_port1, access_port1_vid, vnid);

+        assert(send_edit_config(config["switch_ip"], vtap_conf_xml) == True)

+

+        vtep_conf_xml=get_vtep_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                                lport=network_lport1, 

+                                                src_ip=network_port1_sip, dst_ip=network_port1_dip,

+                                                next_hop_id=network_port1_next_hop_id, 

+                                                vnid=vnid)												

+        logging.info("config VTEP 0x%lx, SRC_IP %s, DST_IP %s, NEXTHOP_ID %d", network_lport1, network_port1_sip, network_port1_dip, network_port1_next_hop_id);                                                

+        assert(send_edit_config(config["switch_ip"], vtep_conf_xml) == True)

+        vtep_conf_xml=get_vtep_lport_config_xml(dp_id=feature_reply.datapath_id, 

+                                                lport=network_lport2, 

+                                                src_ip=network_port2_sip, dst_ip=network_port2_dip,

+                                                next_hop_id=network_port2_next_hop_id, 

+                                                vnid=vnid)												

+        logging.info("config VTEP 0x%lx, SRC_IP %s, DST_IP %s, NEXTHOP_ID %d", network_lport2, network_port2_sip, network_port2_dip, network_port2_next_hop_id);                                                

+        assert(send_edit_config(config["switch_ip"], vtep_conf_xml) == True)

+

+        #add port table to have vxlan ability

+        add_port_table_flow(self.controller)

+

+        #for network port need l2 interface group to decide vlan tag or not

+        add_one_l2_interface_group(self.controller, network_port1_phy_port, vlan_id=network_port1_vlan)

+        add_one_l2_interface_group(self.controller, network_port2_phy_port, vlan_id=network_port2_vlan)

+        #add network mac

+        add_overlay_bridge_flow(self.controller, network_lport1_mac, vnid, network_lport1, False, True)

+        add_overlay_bridge_flow(self.controller, network_lport2_mac, vnid, network_lport2, False, True)

+

+        #add termination table for network port

+        add_termination_flow(self.controller, in_port=network_port1_phy_port, eth_type=0x0800,

+                             dst_mac=switch_cpu_mac, vlanid=network_port1_vlan)

+        add_termination_flow(self.controller, in_port=network_port2_phy_port, eth_type=0x0800,

+                             dst_mac=switch_cpu_mac, vlanid=network_port2_vlan)                             

+        #add vlan table for network port rx packet class vlan

+        add_one_vlan_table_flow(self.controller, of_port=network_port1_phy_port, 

+                                vlan_id=network_port1_vlan)        

+        add_one_vlan_table_flow(self.controller, of_port=network_port2_phy_port, 

+                                vlan_id=network_port2_vlan)        

+        

+        #packet tx on network port 1 rx on network port 2

+        inner_pkt = simple_udp_packet(pktlen=96, eth_dst=network_lport2_mac_str)

+        vxlan_pkt = simple_vxlan_packet(eth_dst=switch_cpu_mac_str,

+                                        vnid=vnid, 

+                                        ip_dst= network_port1_sip, 

+                                        ip_src=network_port1_dip,

+                                        inner_payload=inner_pkt)

+        self.dataplane.send(network_port1_phy_port, str(vxlan_pkt))        

+        #verify     

+        verify_packet(self, str(inner_pkt), network_port2_phy_port)

+        verify_no_other_packets(self)

+

+        

+        

+		#exit verification so clear all configuration

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)   

+        

+        vtap_conf_xml=get_vtap_lport_config_xml(dp_id=feature_reply.datapath_id, 

+		                                        lport=access_lport1, phy_port=access_phy_port1, 

+												vlan=access_port1_vid, vnid=vnid, operation="delete")

+        assert(send_edit_config(config["switch_ip"], vtap_conf_xml) == True)

+          

+        vtep_conf_xml=get_vtep_lport_config_xml(dp_id=feature_reply.datapath_id, 

+		                                        lport=network_lport1, 

+												src_ip=network_port1_sip, dst_ip=network_port1_dip, 

+												next_hop_id=network_port1_next_hop_id, 

+												vnid=vnid, operation="delete")												

+        assert(send_edit_config(config["switch_ip"], vtep_conf_xml) == True)

+        vtep_conf_xml=get_vtep_lport_config_xml(dp_id=feature_reply.datapath_id, 

+		                                        lport=network_lport2, 

+												src_ip=network_port2_sip, dst_ip=network_port2_dip, 

+												next_hop_id=network_port2_next_hop_id, 

+												vnid=vnid, operation="delete")												

+        assert(send_edit_config(config["switch_ip"], vtep_conf_xml) == True)        

+        vni_config_xml=get_vni_config_xml(vni_id=vnid, mcast_ipv4=None, next_hop_id=None, operation="delete")

+        assert(send_edit_config(config["switch_ip"], vni_config_xml) == True)

+        

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=network_port1_next_hop_id, 

+		                                          dst_mac=network_port1_dst_mac, 

+												  phy_port=network_port1_phy_port, 

+												  vlan=network_port1_vlan, operation="delete")

+        assert(send_edit_config(config["switch_ip"], next_hop_conf_xml) == True)

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=network_port2_next_hop_id, 

+		                                          dst_mac=network_port2_dst_mac, 

+												  phy_port=network_port2_phy_port, 

+												  vlan=network_port2_vlan, operation="delete")

+        assert(send_edit_config(config["switch_ip"], next_hop_conf_xml) == True)        

+        next_hop_conf_xml=get_next_hop_config_xml(next_hop_id=next_hop_id_mcast, 

+		                                          dst_mac=dst_mac_mcast, 

+												  phy_port=network_port1_phy_port, 

+												  vlan=network_port1_vlan, operation="delete")

+        assert(send_edit_config(config["switch_ip"], next_hop_conf_xml) == True)

+        
\ No newline at end of file
diff --git a/Fabric/Utilities/acctonUseDpctl/allow_all_ucast_route.py b/Fabric/Utilities/acctonUseDpctl/allow_all_ucast_route.py
new file mode 100755
index 0000000..3e8d1c0
--- /dev/null
+++ b/Fabric/Utilities/acctonUseDpctl/allow_all_ucast_route.py
@@ -0,0 +1,83 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+import logging

+import oftest.base_tests as base_tests

+from oftest import config

+from oftest.testutils import *

+from util import *

+from accton_util import convertIP4toStr as toIpV4Str

+from accton_util import convertMACtoStr as toMacStr

+"""	

+    [Allow all VLAN and unicast route]																				

+		Whatever incoming VLAN tag, do unicast route and output to specified port																			

+																					

+	Inject	eth 1/3	Tag3, SA000000112233, DA000000113355, SIP 192.168.1.100, DIP 192.168.2.2																		

+	Output	eth 1/1	Tag2, SA 000004223355, DA 000004224466																		

+																					

+	dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=3,vlan_vid=0x1000/0x1000 goto:20																				

+	dpctl tcp:192.168.1.1:6633 flow-mod table=20,cmd=add,prio=201 in_port=3,eth_dst=00:00:00:11:33:55,eth_type=0x0800 goto:30																				

+	dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20001 group=any,port=any,weight=0 output=1																				

+	dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:55,set_field=eth_dst=00:00:04:22:44:66,set_field=vlan_vid=2,group=0x20001																				

+	dpctl tcp:192.168.1.1:6633 flow-mod table=30,cmd=add,prio=301 eth_type=0x0800,ip_dst=192.168.2.2/255.255.255.0 write:group=0x20000001 goto:60																				

+	dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x30003 group=any,port=any,weight=0 pop_vlan,output=3																				

+	dpctl tcp:192.168.1.1:6633 flow-mod table=50,cmd=add,prio=501 vlan_vid=3,eth_dst=00:00:00:11:22:33 write:group=0x30003 goto:60																				

+"""

+

+class test1(base_tests.SimpleDataPlane):

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)    

+		

+        test_ports = sorted(config["port_map"].keys())	

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1000/0x1000 goto:20")

+        apply_dpctl_mod(self, config, "flow-mod table=20,cmd=add,prio=201 in_port="+str(input_port)+",eth_dst=00:00:00:11:33:55,eth_type=0x0800 goto:30")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x20000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:55,set_field=eth_dst=00:00:04:22:44:66,set_field=vlan_vid=2,group=0x2000"+str(output_port))

+        apply_dpctl_mod(self, config, "flow-mod table=30,cmd=add,prio=301 eth_type=0x0800,ip_dst=192.168.2.2/255.255.255.0 write:group=0x20000001 goto:60")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x3000"+str(input_port)+" group=any,port=any,weight=0 pop_vlan,output="+str(input_port))

+        apply_dpctl_mod(self, config, "flow-mod table=50,cmd=add,prio=501 vlan_vid=3,eth_dst=00:00:00:11:22:33 write:group=0x3000"+str(input_port)+" goto:60")

+

+        input_pkt = simple_packet(

+                '00 00 00 11 33 55 00 00 00 11 22 33 81 00 00 03 '

+                '08 00 45 00 00 52 00 01 00 00 40 06 f5 ee c0 a8 '

+                '01 64 c0 a8 02 02 04 d2 00 50 00 00 00 00 00 00 '

+                '00 00 50 02 20 00 6c 46 00 00 44 44 44 44 44 44 '

+                '44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 '

+                '44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 '

+                '44 44 44 44')

+

+        output_pkt = simple_packet(

+                '00 00 04 22 44 66 00 00 04 22 33 55 81 00 00 02 '

+                '08 00 45 00 00 52 00 01 00 00 3f 06 f6 ee c0 a8 '

+                '01 64 c0 a8 02 02 04 d2 00 50 00 00 00 00 00 00 '

+                '00 00 50 02 20 00 6c 46 00 00 44 44 44 44 44 44 '

+                '44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 '

+                '44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 '

+                '44 44 44 44')

+        

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+        

+        

+        

+        

+        

+        
\ No newline at end of file
diff --git a/Fabric/Utilities/acctonUseDpctl/basic.py b/Fabric/Utilities/acctonUseDpctl/basic.py
new file mode 100755
index 0000000..32dfa6f
--- /dev/null
+++ b/Fabric/Utilities/acctonUseDpctl/basic.py
@@ -0,0 +1,87 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+import logging

+import oftest.base_tests as base_tests

+from oftest import config

+from oftest.testutils import *

+from util import *

+

+

+class features(base_tests.SimpleDataPlane):

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        json_result = apply_dpctl_get_cmd(self, config, "features")

+        #pprint(json_result)

+        result=json_result["RECEIVED"][1]

+        #self.assertTrue(result["tabs"]==64, "Table size is not correct")

+        self.assertNotEqual(result["caps"], 0, "Invalid capabilities")

+

+class get_config(base_tests.SimpleDataPlane):

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        json_result = apply_dpctl_get_cmd(self, config, "get-config")

+        #pprint(json_result)

+        result=json_result["RECEIVED"][1]

+        self.assertNotEqual(result["conf"], {}, "Config reply nothing")

+

+class desc(base_tests.SimpleDataPlane):

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        json_result = apply_dpctl_get_cmd(self, config, "stats-desc")

+        #pprint(json_result)

+        result=json_result["RECEIVED"][1]

+        self.assertNotEqual(result["mfr"], {}, "DESC MFR reply nothing")

+

+class port_desc(base_tests.SimpleDataPlane):

+    def runTest(self):

+        json_result = apply_dpctl_get_cmd(self, config, "port-desc")

+        #pprint(json_result)

+        result=json_result["RECEIVED"][1]

+        self.assertNotEqual(result["port"], {}, "Port DESC reply nothing")

+

+class table_features(base_tests.SimpleDataPlane):

+    def runTest(self):

+        json_result = apply_dpctl_get_cmd(self, config, "table-features")

+        #pprint(json_result)

+        result=json_result["RECEIVED"][1]

+        self.assertNotEqual(result["table_features"], {}, "Table features reply nothing")

+

+class group_features(base_tests.SimpleDataPlane):

+    def runTest(self):

+        json_result = apply_dpctl_get_cmd(self, config, "group-features")

+        #pprint(json_result)

+        result=json_result["RECEIVED"][1]

+        self.assertNotEqual(result["types"], 0, "Not support group types")

+

+class meter_features(base_tests.SimpleDataPlane):

+    def runTest(self):

+        json_result = apply_dpctl_get_cmd(self, config, "meter-features")

+        #pprint(json_result)

+        result=json_result["RECEIVED"][1]["features"][0]

+        self.assertNotEqual(result["max_meter"], 0, "Not support meter")

+

+

diff --git a/Fabric/Utilities/acctonUseDpctl/meter.py b/Fabric/Utilities/acctonUseDpctl/meter.py
new file mode 100755
index 0000000..700eba4
--- /dev/null
+++ b/Fabric/Utilities/acctonUseDpctl/meter.py
@@ -0,0 +1,279 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+import logging

+import oftest.base_tests as base_tests

+from oftest import config

+from oftest.testutils import *

+from util import *

+from accton_util import convertIP4toStr as toIpV4Str

+from accton_util import convertMACtoStr as toMacStr

+

+"""

+Not verify yet, need to think how to verify meter

+"""

+

+class dscp(base_tests.SimpleDataPlane):

+    """

+    [DSCP meter]

+      DSCP meter

+

+    Inject  eth 1/3 {DA000000113355, SA000000112233, Tag 2} pkt [100* 10 pkt/sec]

+    Output  eth 1/1 [10] no change

+

+    Inject  eth 1/3 {DA000000113355, SA000000112233, Tag 2} pkt [100 bytes, 10 burst]

+    Output  eth 1/1 [8] no change; [2] dscp 2

+

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=3,vlan_vid=0x1002/0x1fff goto:20

+    ./dpctl tcp:192.168.1.1:6633 meter-mod cmd=add,flags=0x06,meter=1 dscp_remark:rate=5,prec_level=2,burst=5

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20001 group=any,port=any,weight=0 output=1

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=60,cmd=add,prio=601 eth_dst=00:00:00:11:33:55 write:group=0x20001 meter:1

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1002/0x1fff goto:20")

+        apply_dpctl_mod(self, config, "meter-mod cmd=add,flags=0x06,meter=1 dscp_remark:rate=5,prec_level=2,burst=5")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "flow-mod table=60,cmd=add,prio=601 eth_dst=00:00:00:11:33:55 write:group=0x2000"+str(output_port)+" meter:1")

+

+        input_pkt = simple_tcp_packet(eth_dst="00:00:00:11:33:55",

+                                      eth_src="00:00:00:11:22:33",

+                                      ip_src=toIpV4Str(0xc0a80164),

+                                      ip_dst=toIpV4Str(0xc0a80202),

+                                      dl_vlan_enable=True,

+                                      vlan_vid=2)

+

+        output_pkt = input_pkt

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+

+

+class drop(base_tests.SimpleDataPlane):

+    """

+    [Drop meter]

+        Drop meter

+

+    Inject  eth 1/3 {DA000000113355, SA000000112233, Tag 2} pkt [100 bytes, 10 pkt/sec]

+    Output  eth 1/1 [8] output

+

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=3,vlan_vid=0x1002/0x1fff goto:20

+    ./dpctl tcp:192.168.1.1:6633 meter-mod cmd=add,flags=0x01,meter=1 drop:rate=8

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20001 group=any,port=any,weight=0 output=1

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=60,cmd=add,prio=601 eth_dst=00:00:00:11:33:55 write:group=0x20001 meter:1

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1002/0x1fff goto:20")

+        apply_dpctl_mod(self, config, "meter-mod cmd=add,flags=0x01,meter=1 drop:rate=8")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "flow-mod table=60,cmd=add,prio=601 eth_dst=00:00:00:11:33:55 write:group=0x2000"+str(output_port)+" meter:1")

+

+        input_pkt = simple_tcp_packet(eth_dst="00:00:00:11:33:55",

+                                      eth_src="00:00:00:11:22:33",

+                                      ip_src=toIpV4Str(0xc0a80164),

+                                      ip_dst=toIpV4Str(0xc0a80202),

+                                      dl_vlan_enable=True,

+                                      vlan_vid=2)

+

+        output_pkt = input_pkt

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+

+

+class trtcm(base_tests.SimpleDataPlane):

+    """

+    [TrTCM meter]

+        TrTCM meter

+

+    Inject  eth 1/3 {DA000000113355, SA000000112233, Tag 2} pkt [100 bytes, 50 pkt/sec]

+    Output  eth 1/1 [16] vlan pcp 1 + [14] vlan pcp 3 + [20] vlan pcp 5

+

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=3,vlan_vid=0x1002/0x1fff goto:20

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20001 group=any,port=any,weight=0 output=1

+    ./dpctl tcp:192.168.1.1:6633 meter-mod cmd=add,flags=0x6,meter=1 set_color:rate=10,burst=5,exp_id=0x1018,exp_type=3,mode=1,color_aware=0,color=1 set_color:rate=20,burst=10,exp_id=0x1018,exp_type=3,mode=1,color_aware=0,color=2

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=60,cmd=add,prio=601 eth_dst=00:00:00:11:33:55 write:group=0x20001 apply:set_field=ofdpa_color_actions_index:1 goto:65 meter:1

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=65,cmd=add,prio=651 ofdpa_color=2,ofdpa_color_actions_index=1 apply:set_field=vlan_pcp:5

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=65,cmd=add,prio=651 ofdpa_color=1,ofdpa_color_actions_index=1 apply:set_field=vlan_pcp:3

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=65,cmd=add,prio=651 ofdpa_color=0,ofdpa_color_actions_index=1 apply:set_field=vlan_pcp:1

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1002/0x1fff goto:20")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "meter-mod cmd=add,flags=0x6,meter=1 set_color:rate=10,burst=5,exp_id=0x1018,exp_type=3,mode=1,color_aware=0,color=1 set_color:rate=20,burst=10,exp_id=0x1018,exp_type=3,mode=1,color_aware=0,color=2")

+        apply_dpctl_mod(self, config, "flow-mod table=60,cmd=add,prio=601 eth_dst=00:00:00:11:33:55 write:group=0x2000"+str(output_port)+" apply:set_field=ofdpa_color_actions_index:1 goto:65 meter:1")

+        apply_dpctl_mod(self, config, "flow-mod table=65,cmd=add,prio=651 ofdpa_color=2,ofdpa_color_actions_index=1 apply:set_field=vlan_pcp:5")

+        apply_dpctl_mod(self, config, "flow-mod table=65,cmd=add,prio=651 ofdpa_color=1,ofdpa_color_actions_index=1 apply:set_field=vlan_pcp:3")

+        apply_dpctl_mod(self, config, "flow-mod table=65,cmd=add,prio=651 ofdpa_color=0,ofdpa_color_actions_index=1 apply:set_field=vlan_pcp:1")

+

+        input_pkt = simple_tcp_packet(eth_dst="00:00:00:11:33:55",

+                                      eth_src="00:00:00:11:22:33",

+                                      ip_src=toIpV4Str(0xc0a80164),

+                                      ip_dst=toIpV4Str(0xc0a80202),

+                                      dl_vlan_enable=True,

+                                      vlan_vid=2,

+                                      vlan_pcp=0)

+

+        output_pkt = simple_tcp_packet(eth_dst="00:00:00:11:33:55",

+                                      eth_src="00:00:00:11:22:33",

+                                      ip_src=toIpV4Str(0xc0a80164),

+                                      ip_dst=toIpV4Str(0xc0a80202),

+                                      dl_vlan_enable=True,

+                                      vlan_vid=2,

+                                      vlan_pcp=1)

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+

+

+class srtcm(base_tests.SimpleDataPlane):

+    """

+    [SrTCM meter]

+        SrTCM meter

+

+    Inject  eth 1/3 {DA000000113355, SA000000112233, Tag 2} pkt [100 bytes, 50 pkt/sec]

+    Output  eth 1/1 [15] vlan pcp 1 + [15] vlan pcp 3 + [20] vlan pcp 5

+

+    Inject  eth 1/3 {DA000000113355, SA000000112233, Tag 2} pkt [100 bytes, 30 pkt/sec]

+    Output  eth 1/1 [15] vlan pcp 1 + [15] vlan pcp 3

+

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=3,vlan_vid=0x1002/0x1fff goto:20

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20001 group=any,port=any,weight=0 output=1

+    ./dpctl tcp:192.168.1.1:6633 meter-mod cmd=add,flags=0x6,meter=1 set_color:rate=10,exp_id=0x1018,exp_type=3,mode=2,color_aware=0,color=1,burst=10 set_color:rate=20,exp_id=0x1018,exp_type=3,mode=2,color_aware=0,color=2,burst=20

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=60,cmd=add,prio=601 eth_dst=00:00:00:11:33:55 write:group=0x20001 apply:set_field=ofdpa_color_actions_index:1 goto:65 meter:1

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=65,cmd=add,prio=651 ofdpa_color=2,ofdpa_color_actions_index=1 apply:set_field=vlan_pcp:5

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=65,cmd=add,prio=651 ofdpa_color=1,ofdpa_color_actions_index=1 apply:set_field=vlan_pcp:3

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=65,cmd=add,prio=651 ofdpa_color=0,ofdpa_color_actions_index=1 apply:set_field=vlan_pcp:1

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1002/0x1fff goto:20")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "meter-mod cmd=add,flags=0x6,meter=1 set_color:rate=10,exp_id=0x1018,exp_type=3,mode=2,color_aware=0,color=1,burst=10 set_color:rate=20,exp_id=0x1018,exp_type=3,mode=2,color_aware=0,color=2,burst=20")

+        apply_dpctl_mod(self, config, "flow-mod table=60,cmd=add,prio=601 eth_dst=00:00:00:11:33:55 write:group=0x2000"+str(output_port)+" apply:set_field=ofdpa_color_actions_index:1 goto:65 meter:1")

+        apply_dpctl_mod(self, config, "flow-mod table=65,cmd=add,prio=651 ofdpa_color=2,ofdpa_color_actions_index=1 apply:set_field=vlan_pcp:5")

+        apply_dpctl_mod(self, config, "flow-mod table=65,cmd=add,prio=651 ofdpa_color=1,ofdpa_color_actions_index=1 apply:set_field=vlan_pcp:3")

+        apply_dpctl_mod(self, config, "flow-mod table=65,cmd=add,prio=651 ofdpa_color=0,ofdpa_color_actions_index=1 apply:set_field=vlan_pcp:1")

+

+        input_pkt = simple_tcp_packet(eth_dst="00:00:00:11:33:55",

+                                      eth_src="00:00:00:11:22:33",

+                                      ip_src=toIpV4Str(0xc0a80164),

+                                      ip_dst=toIpV4Str(0xc0a80202),

+                                      dl_vlan_enable=True,

+                                      vlan_vid=2,

+                                      vlan_pcp=0)

+

+        output_pkt = simple_tcp_packet(eth_dst="00:00:00:11:33:55",

+                                      eth_src="00:00:00:11:22:33",

+                                      ip_src=toIpV4Str(0xc0a80164),

+                                      ip_dst=toIpV4Str(0xc0a80202),

+                                      dl_vlan_enable=True,

+                                      vlan_vid=2,

+                                      vlan_pcp=1)

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+

+

+class mod_trtcm(base_tests.SimpleDataPlane):

+    """

+    [Mod TrTCM meter]

+        Mod TrTCM meter

+

+    Inject  eth 1/3 {DA000000113355, SA000000112233, Tag 2} pkt [100 bytes, 50 pkt/sec]

+    Output  eth 1/1  [15] vlan pcp 1 + [28] vlan pcp 3 + [7] vlan pcp 5

+

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=3,vlan_vid=0x1002/0x1fff goto:20

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20001 group=any,port=any,weight=0 output=1

+    ./dpctl tcp:192.168.1.1:6633 meter-mod cmd=add,flags=0x6,meter=1 set_color:rate=10,burst=5,exp_id=0x1018,exp_type=3,mode=3,color_aware=0,color=1 set_color:rate=20,burst=10,exp_id=0x1018,exp_type=3,mode=3,color_aware=0,color=2

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=60,cmd=add,prio=601 eth_dst=00:00:00:11:33:55 write:group=0x20001 apply:set_field=ofdpa_color_actions_index:1 goto:65 meter:1

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=65,cmd=add,prio=651 ofdpa_color=2,ofdpa_color_actions_index=1 apply:set_field=vlan_pcp:5

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=65,cmd=add,prio=651 ofdpa_color=1,ofdpa_color_actions_index=1 apply:set_field=vlan_pcp:3

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=65,cmd=add,prio=651 ofdpa_color=0,ofdpa_color_actions_index=1 apply:set_field=vlan_pcp:1

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1002/0x1fff goto:20")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "meter-mod cmd=add,flags=0x6,meter=1 set_color:rate=10,burst=5,exp_id=0x1018,exp_type=3,mode=3,color_aware=0,color=1 set_color:rate=20,burst=10,exp_id=0x1018,exp_type=3,mode=3,color_aware=0,color=2")

+        apply_dpctl_mod(self, config, "flow-mod table=60,cmd=add,prio=601 eth_dst=00:00:00:11:33:55 write:group=0x2000"+str(output_port)+" apply:set_field=ofdpa_color_actions_index:1 goto:65 meter:1")

+        apply_dpctl_mod(self, config, "flow-mod table=65,cmd=add,prio=651 ofdpa_color=2,ofdpa_color_actions_index=1 apply:set_field=vlan_pcp:5")

+        apply_dpctl_mod(self, config, "flow-mod table=65,cmd=add,prio=651 ofdpa_color=1,ofdpa_color_actions_index=1 apply:set_field=vlan_pcp:3")

+        apply_dpctl_mod(self, config, "flow-mod table=65,cmd=add,prio=651 ofdpa_color=0,ofdpa_color_actions_index=1 apply:set_field=vlan_pcp:1")

+

+        input_pkt = simple_tcp_packet(eth_dst="00:00:00:11:33:55",

+                                      eth_src="00:00:00:11:22:33",

+                                      ip_src=toIpV4Str(0xc0a80164),

+                                      ip_dst=toIpV4Str(0xc0a80202),

+                                      dl_vlan_enable=True,

+                                      vlan_vid=2,

+                                      vlan_pcp=0)

+

+        output_pkt = simple_tcp_packet(eth_dst="00:00:00:11:33:55",

+                                      eth_src="00:00:00:11:22:33",

+                                      ip_src=toIpV4Str(0xc0a80164),

+                                      ip_dst=toIpV4Str(0xc0a80202),

+                                      dl_vlan_enable=True,

+                                      vlan_vid=2,

+                                      vlan_pcp=1)

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+

+

+

diff --git a/Fabric/Utilities/acctonUseDpctl/mpls.py b/Fabric/Utilities/acctonUseDpctl/mpls.py
new file mode 100755
index 0000000..a4399d7
--- /dev/null
+++ b/Fabric/Utilities/acctonUseDpctl/mpls.py
@@ -0,0 +1,1100 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+import logging

+import oftest.base_tests as base_tests

+import time

+from oftest import config

+from oftest.testutils import *

+from util import *

+from accton_util import convertIP4toStr as toIpV4Str

+from accton_util import convertMACtoStr as toMacStr

+

+class encap_mpls(base_tests.SimpleDataPlane):

+    """

+    [Encap one MPLS label]

+      Encap a MPLS label

+

+    Inject  eth 1/3 Tag 3, SA000000112233, DA000000113355, V4

+    Output  eth 1/1 Tag 2, SA000004223355, DA000004224466, MPLS label 2305, EXP7, BoS1, TTL250, CW

+

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20001 group=any,port=any,weight=0 output=1

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=24,cmd=add,prio=204 eth_type=0x8847,mpls_label=0x901,mpls_bos=1 apply:pop_mpls=0x8847,mpls_dec,ofdpa_pop_l2hdr,ofdpa_pop_cw,set_field=ofdpa_mpls_l2_port:0x20100,set_field=tunn_id:0x10001 write:group=0x20001 goto:60

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x90000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:55,set_field=eth_dst=00:00:04:22:44:66,set_field=vlan_vid=2,group=0x20001

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x91000001 group=any,port=any,weight=0 set_field=mpls_label:0x901,set_field=mpls_tc:7,set_field=ofdpa_mpls_ttl:250,ofdpa_push_l2hdr,push_vlan=0x8100,push_mpls=0x8847,ofdpa_push_cw,group=0x90000001

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=13,cmd=add,prio=113 tunn_id=0x10001,ofdpa_mpls_l2_port=100 write:group=0x91000001 goto:60

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=3 apply:set_field=ofdpa_mpls_l2_port:100,set_field=tunn_id:0x10001 goto:13

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=1,vlan_vid=0x1002/0x1fff goto:20

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=20,cmd=add,prio=201 in_port=1,vlan_vid=2/0xfff,eth_dst=00:00:04:22:33:55,eth_type=0x8847 goto:24

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "flow-mod table=24,cmd=add,prio=204 eth_type=0x8847,mpls_label=0x901,mpls_bos=1 apply:pop_mpls=0x8847,mpls_dec,ofdpa_pop_l2hdr,ofdpa_pop_cw,set_field=ofdpa_mpls_l2_port:0x20100,set_field=tunn_id:0x10001 write:group=0x2000"+str(output_port)+" goto:60")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x90000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:55,set_field=eth_dst=00:00:04:22:44:66,set_field=vlan_vid=2,group=0x2000"+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x91000001 group=any,port=any,weight=0 set_field=mpls_label:0x901,set_field=mpls_tc:7,set_field=ofdpa_mpls_ttl:250,ofdpa_push_l2hdr,push_vlan=0x8100,push_mpls=0x8847,ofdpa_push_cw,group=0x90000001")

+        apply_dpctl_mod(self, config, "flow-mod table=13,cmd=add,prio=113 tunn_id=0x10001,ofdpa_mpls_l2_port=100 write:group=0x91000001 goto:60")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+" apply:set_field=ofdpa_mpls_l2_port:100,set_field=tunn_id:0x10001 goto:13")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(output_port)+",vlan_vid=0x1002/0x1fff goto:20")

+        apply_dpctl_mod(self, config, "flow-mod table=20,cmd=add,prio=201 in_port="+str(output_port)+",vlan_vid=2/0xfff,eth_dst=00:00:04:22:33:55,eth_type=0x8847 goto:24")

+

+        input_pkt = simple_packet(

+                '00 00 00 11 33 55 00 00 00 11 22 33 81 00 00 03 '

+                '08 00 45 00 00 2e 04 d2 00 00 7f 00 b2 47 c0 a8 '

+                '01 64 c0 a8 02 02 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        output_pkt = simple_packet(

+                '00 00 04 22 44 66 00 00 04 22 33 55 81 00 00 02 '

+                '88 47 00 90 1f fa 00 00 00 00 00 00 00 11 33 55 '

+                '00 00 00 11 22 33 81 00 00 03 08 00 45 00 00 2e '

+                '04 d2 00 00 7f 00 b2 47 c0 a8 01 64 c0 a8 02 02 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+

+

+class decap_mpls(base_tests.SimpleDataPlane):

+    """

+    [Decap one MPLS label]

+      Decap the MPLS label

+

+    Inject  eth 1/1 Tag 2, SA000004223355, DA000004224466, MPLS label 2305, EXP7, BoS1, TTL250, CW, InSA000000112233, InDA000000113355

+    Output  eth 1/3 SA000000112233, DA000000113355

+

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20001 group=any,port=any,weight=0 output=1

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=24,cmd=add,prio=204 eth_type=0x8847,mpls_label=0x901,mpls_bos=1 apply:pop_mpls=0x8847,mpls_dec,ofdpa_pop_l2hdr,ofdpa_pop_cw,set_field=ofdpa_mpls_l2_port:0x20100,set_field=tunn_id:0x10001 write:group=0x20001 goto:60

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x90000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:55,set_field=eth_dst=00:00:04:22:44:66,set_field=vlan_vid=2,group=0x20001

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x91000001 group=any,port=any,weight=0 set_field=mpls_label:0x901,set_field=mpls_tc:7,set_field=ofdpa_mpls_ttl:250,ofdpa_push_l2hdr,push_vlan=0x8100,push_mpls=0x8847,ofdpa_push_cw,group=0x90000001

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=13,cmd=add,prio=113 tunn_id=0x10001,ofdpa_mpls_l2_port=100 write:group=0x91000001 goto:60

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=3 apply:set_field=ofdpa_mpls_l2_port:100,set_field=tunn_id:0x10001 goto:13

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=1,vlan_vid=0x1002/0x1fff goto:20

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=20,cmd=add,prio=201 in_port=1,vlan_vid=2/0xfff,eth_dst=00:00:04:22:33:55,eth_type=0x8847 goto:24

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(input_port)+" group=any,port=any,weight=0 output="+str(input_port))

+        apply_dpctl_mod(self, config, "flow-mod table=24,cmd=add,prio=204 eth_type=0x8847,mpls_label=0x901,mpls_bos=1 apply:pop_mpls=0x8847,mpls_dec,ofdpa_pop_l2hdr,ofdpa_pop_cw,set_field=ofdpa_mpls_l2_port:0x20100,set_field=tunn_id:0x10001 write:group=0x2000"+str(input_port)+" goto:60")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x90000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:55,set_field=eth_dst=00:00:04:22:44:66,set_field=vlan_vid=2,group=0x2000"+str(input_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x91000001 group=any,port=any,weight=0 set_field=mpls_label:0x901,set_field=mpls_tc:7,set_field=ofdpa_mpls_ttl:250,ofdpa_push_l2hdr,push_vlan=0x8100,push_mpls=0x8847,ofdpa_push_cw,group=0x90000001")

+        apply_dpctl_mod(self, config, "flow-mod table=13,cmd=add,prio=113 tunn_id=0x10001,ofdpa_mpls_l2_port=100 write:group=0x91000001 goto:60")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(output_port)+" apply:set_field=ofdpa_mpls_l2_port:100,set_field=tunn_id:0x10001 goto:13")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1002/0x1fff goto:20")

+        apply_dpctl_mod(self, config, "flow-mod table=20,cmd=add,prio=201 in_port="+str(input_port)+",vlan_vid=2/0xfff,eth_dst=00:00:04:22:33:55,eth_type=0x8847 goto:24")

+

+        input_pkt = simple_packet(

+                '00 00 04 22 33 55 00 00 04 22 44 66 81 00 00 02 '

+                '88 47 00 90 1f fa 00 00 00 00 00 00 00 11 33 55 '

+                '00 00 00 11 22 33 81 00 00 05 08 00 45 00 00 2e '

+                '04 d2 00 00 7f 00 b1 aa c0 a8 02 01 c0 a8 02 02 '

+                '00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f '

+                '10 11 12 13 14 15 16 17 18 19 00 00 00 00')

+

+        output_pkt = simple_packet(

+                '00 00 00 11 33 55 00 00 00 11 22 33 81 00 00 05 '

+                '08 00 45 00 00 2e 04 d2 00 00 7f 00 b1 aa c0 a8 '

+                '02 01 c0 a8 02 02 00 01 02 03 04 05 06 07 08 09 '

+                '0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 '

+                '00 00 00 00')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+

+

+class encap_2mpls(base_tests.SimpleDataPlane):

+    """

+    [Encap two MPLS labels]

+      Encap two MPLS labels

+

+    Inject  eth 1/3 Tag 3, SA000000112233, DA000000113355

+    Output  eth 1/1 Tag 2, Outer label 0x903, TTL 250, InLabel 0x901, TTL 250, SA000004223355, DA000004224466

+

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20001 group=any,port=any,weight=0 output=1

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=24,cmd=add,prio=204 eth_type=0x8847,mpls_label=0x901,mpls_bos=1 apply:pop_mpls=0x8847,mpls_dec,ofdpa_pop_l2hdr,ofdpa_pop_cw,set_field=ofdpa_mpls_l2_port:0x20100,set_field=tunn_id:0x10001 write:group=0x20001 goto:60

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x90000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:55,set_field=eth_dst=00:00:04:22:44:66,set_field=vlan_vid=2,group=0x20001

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x93000001 group=any,port=any,weight=0 push_mpls=0x8847,set_field=mpls_label:0x903,group=0x90000001

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x91000001 group=any,port=any,weight=0 set_field=mpls_label:0x901,set_field=mpls_tc:7,set_field=ofdpa_mpls_ttl:250,ofdpa_push_l2hdr,push_vlan=0x8100,push_mpls=0x8847,ofdpa_push_cw,group=0x93000001

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=13,cmd=add,prio=113 tunn_id=0x10001,ofdpa_mpls_l2_port=100 write:group=0x91000001 goto:60

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=3,vlan_vid=0x1003/0x1fff apply:set_field=ofdpa_mpls_l2_port:100,set_field=tunn_id:0x10001 goto:13

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "flow-mod table=24,cmd=add,prio=204 eth_type=0x8847,mpls_label=0x901,mpls_bos=1 apply:pop_mpls=0x8847,mpls_dec,ofdpa_pop_l2hdr,ofdpa_pop_cw,set_field=ofdpa_mpls_l2_port:0x20100,set_field=tunn_id:0x10001 write:group=0x2000"+str(output_port)+" goto:60")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x90000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:55,set_field=eth_dst=00:00:04:22:44:66,set_field=vlan_vid=2,group=0x2000"+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x93000001 group=any,port=any,weight=0 push_mpls=0x8847,set_field=mpls_label:0x903,group=0x90000001")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x91000001 group=any,port=any,weight=0 set_field=mpls_label:0x901,set_field=mpls_tc:7,set_field=ofdpa_mpls_ttl:250,ofdpa_push_l2hdr,push_vlan=0x8100,push_mpls=0x8847,ofdpa_push_cw,group=0x93000001")

+        apply_dpctl_mod(self, config, "flow-mod table=13,cmd=add,prio=113 tunn_id=0x10001,ofdpa_mpls_l2_port=100 write:group=0x91000001 goto:60")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1003/0x1fff apply:set_field=ofdpa_mpls_l2_port:100,set_field=tunn_id:0x10001 goto:13")

+

+        input_pkt = simple_packet(

+                '00 00 00 11 33 55 00 00 00 11 22 33 81 00 00 03 '

+                '08 00 45 00 00 2e 04 d2 00 00 7f 00 b2 47 c0 a8 '

+                '01 64 c0 a8 02 02 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        output_pkt = simple_packet(

+                '00 00 04 22 44 66 00 00 04 22 33 55 81 00 00 02 '

+                '88 47 00 90 3e fa 00 90 1f fa 00 00 00 00 00 00 '

+                '00 11 33 55 00 00 00 11 22 33 81 00 00 03 08 00 '

+                '45 00 00 2e 04 d2 00 00 7f 00 b2 47 c0 a8 01 64 '

+                'c0 a8 02 02 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+

+

+class encap_3mpls(base_tests.SimpleDataPlane):

+    """

+    [Encap 3 MPLS labels]

+      Encap 3 MPLS labels

+

+    Inject  eth 1/3 Tag 3, SA000000112233, DA000000113355

+    Output  eth 1/1 Tag 2, Outest label 0x904, TTL 250, Middle label 0x903, InLabel 0x901, SA000004223355, DA000004224466

+

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20001 group=any,port=any,weight=0 output=1

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=24,cmd=add,prio=204 eth_type=0x8847,mpls_label=0x901,mpls_bos=1 apply:pop_mpls=0x8847,mpls_dec,ofdpa_pop_l2hdr,ofdpa_pop_cw,set_field=ofdpa_mpls_l2_port:0x20100,set_field=tunn_id:0x10001 write:group=0x20001 goto:60

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x90000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:55,set_field=eth_dst=00:00:04:22:44:66,set_field=vlan_vid=2,group=0x20001

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x94000001 group=any,port=any,weight=0 push_mpls=0x8847,set_field=mpls_label:0x904,group=0x90000001

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x93000001 group=any,port=any,weight=0 push_mpls=0x8847,set_field=mpls_label:0x903,group=0x94000001

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x91000001 group=any,port=any,weight=0 set_field=mpls_label:0x901,set_field=mpls_tc:7,set_field=ofdpa_mpls_ttl:250,ofdpa_push_l2hdr,push_vlan=0x8100,push_mpls=0x8847,ofdpa_push_cw,group=0x93000001

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=13,cmd=add,prio=113 tunn_id=0x10001,ofdpa_mpls_l2_port=100 write:group=0x91000001 goto:60

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=3,vlan_vid=0x1003/0x1fff apply:set_field=ofdpa_mpls_l2_port:100,set_field=tunn_id:0x10001 goto:13

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "flow-mod table=24,cmd=add,prio=204 eth_type=0x8847,mpls_label=0x901,mpls_bos=1 apply:pop_mpls=0x8847,mpls_dec,ofdpa_pop_l2hdr,ofdpa_pop_cw,set_field=ofdpa_mpls_l2_port:0x20100,set_field=tunn_id:0x10001 write:group=0x2000"+str(output_port)+" goto:60")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x90000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:55,set_field=eth_dst=00:00:04:22:44:66,set_field=vlan_vid=2,group=0x2000"+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x94000001 group=any,port=any,weight=0 push_mpls=0x8847,set_field=mpls_label:0x904,group=0x90000001")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x93000001 group=any,port=any,weight=0 push_mpls=0x8847,set_field=mpls_label:0x903,group=0x94000001")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x91000001 group=any,port=any,weight=0 set_field=mpls_label:0x901,set_field=mpls_tc:7,set_field=ofdpa_mpls_ttl:250,ofdpa_push_l2hdr,push_vlan=0x8100,push_mpls=0x8847,ofdpa_push_cw,group=0x93000001")

+        apply_dpctl_mod(self, config, "flow-mod table=13,cmd=add,prio=113 tunn_id=0x10001,ofdpa_mpls_l2_port=100 write:group=0x91000001 goto:60")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1003/0x1fff apply:set_field=ofdpa_mpls_l2_port:100,set_field=tunn_id:0x10001 goto:13")

+

+        input_pkt = simple_packet(

+                '00 00 00 11 33 55 00 00 00 11 22 33 81 00 00 03 '

+                '08 00 45 00 00 2e 04 d2 00 00 7f 00 b2 47 c0 a8 '

+                '01 64 c0 a8 02 02 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        output_pkt = simple_packet(

+                '00 00 04 22 44 66 00 00 04 22 33 55 81 00 00 02 '

+                '88 47 00 90 4e fa 00 90 3e fa 00 90 1f fa 00 00 '

+                '00 00 00 00 00 11 33 55 00 00 00 11 22 33 81 00 '

+                '00 03 08 00 45 00 00 2e 04 d2 00 00 7f 00 b2 47 '

+                'c0 a8 01 64 c0 a8 02 02 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+

+

+class decap_penultimate_mpls(base_tests.SimpleDataPlane):

+    """

+    [Penultimate Hop Pop]

+      Pop outermost tunnel label

+

+    Inject  eth 1/1 Tag 2, Outer label 0x901, InLabel 0xF, SA000004223355, DA000004224466

+    Output  eth 1/3 Tag 2, label 0xF, SA000004223355, DA000004224466

+

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20003 group=any,port=any,weight=0 output=3

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x90000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:55,set_field=eth_dst=00:00:04:22:44:66,set_field=vlan_vid=2,group=0x20003

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=24,cmd=add,prio=204 eth_type=0x8847,mpls_label=0x901 apply:pop_mpls=0x8847,mpls_dec write:group=0x90000001 goto:60

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=1,vlan_vid=0x1002/0x1fff goto:20

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=20,cmd=add,prio=201 in_port=1,vlan_vid=2/0xfff,eth_dst=00:00:04:22:33:55,eth_type=0x8847 goto:24

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x90000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:55,set_field=eth_dst=00:00:04:22:44:66,set_field=vlan_vid=2,group=0x2000"+str(output_port))

+        apply_dpctl_mod(self, config, "flow-mod table=24,cmd=add,prio=204 eth_type=0x8847,mpls_label=0x901 apply:pop_mpls=0x8847,mpls_dec write:group=0x90000001 goto:60")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1002/0x1fff goto:20")

+        apply_dpctl_mod(self, config, "flow-mod table=20,cmd=add,prio=201 in_port="+str(input_port)+",vlan_vid=2/0xfff,eth_dst=00:00:04:22:33:55,eth_type=0x8847 goto:24")

+

+        input_pkt = simple_packet(

+                '00 00 04 22 33 55 00 00 04 22 44 66 81 00 00 02 '

+                '88 47 00 90 1e fa 00 01 0b ff 00 00 00 00 00 00 '

+                '00 11 33 55 00 00 00 11 22 33 81 00 00 05 08 00 '

+                '45 00 00 2e 04 d2 00 00 7f 00 b1 aa c0 a8 02 01 '

+                'c0 a8 02 02 00 01 02 03 04 05 06 07 08 09 0a 0b '

+                '0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19')

+

+        output_pkt = simple_packet(

+                '00 00 04 22 44 66 00 00 04 22 33 55 81 00 00 02 '

+                '88 47 00 01 0f f9 00 00 00 00 00 00 00 11 33 55 '

+                '00 00 00 11 22 33 81 00 00 05 08 00 45 00 00 2e '

+                '04 d2 00 00 7f 00 b1 aa c0 a8 02 01 c0 a8 02 02 '

+                '00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f '

+                '10 11 12 13 14 15 16 17 18 19')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+

+

+class decap_2mpls(base_tests.SimpleDataPlane):

+    """

+    [Pop, decap, and L2 forward]

+      Pop outermost tunnel label and pop outer L2 header (L2 Switch VPWS )

+

+    Inject  eth 1/1 Tag 2, Outer label 0x903, InLabel 0x901, SA000004223355, DA000004224466; InTag 5, InSA000000112233, InDA000000113355

+    Output  eth 1/3 Tag 5, SA000000112233, DA000000113355

+

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20001 group=any,port=any,weight=0 output=1

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x90000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:55,set_field=eth_dst=00:00:04:22:44:66,set_field=vlan_vid=2,group=0x20001

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x93000001 group=any,port=any,weight=0 set_field=mpls_label:0x903,push_mpls=0x8847,group=0x90000001

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x91000001 group=any,port=any,weight=0 set_field=mpls_label:0x901,set_field=mpls_tc:7,set_field=ofdpa_mpls_ttl:250,ofdpa_push_l2hdr,push_vlan=0x8100,push_mpls=0x8847,ofdpa_push_cw,group=0x93000001

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=13,cmd=add,prio=113 tunn_id=0x10001,ofdpa_mpls_l2_port=100 write:group=0x91000001 goto:60

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=3,vlan_vid=0x1003/0x1fff apply:set_field=ofdpa_mpls_l2_port:100,set_field=tunn_id:0x10001 goto:13

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=1,vlan_vid=0x1002/0x1fff goto:20

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=20,cmd=add,prio=201 in_port=1,vlan_vid=2/0xfff,eth_dst=00:00:04:22:33:55,eth_type=0x00008847 goto:24

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=23,cmd=add,prio=203 eth_type=0x8847,mpls_label=0x903 apply:pop_mpls=0x8847,mpls_dec goto:24

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=24,cmd=add,prio=204 eth_type=0x8847,mpls_label=0x901,mpls_bos=1 apply:pop_mpls=0x8847,mpls_dec,ofdpa_pop_l2hdr,ofdpa_pop_cw,set_field=ofdpa_mpls_l2_port:0x20100,set_field=tunn_id:0x10001 write:group=0x20001 goto:60

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(input_port)+" group=any,port=any,weight=0 output="+str(input_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x90000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:55,set_field=eth_dst=00:00:04:22:44:66,set_field=vlan_vid=2,group=0x2000"+str(input_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x93000001 group=any,port=any,weight=0 set_field=mpls_label:0x903,push_mpls=0x8847,group=0x90000001")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x91000001 group=any,port=any,weight=0 set_field=mpls_label:0x901,set_field=mpls_tc:7,set_field=ofdpa_mpls_ttl:250,ofdpa_push_l2hdr,push_vlan=0x8100,push_mpls=0x8847,ofdpa_push_cw,group=0x93000001")

+        apply_dpctl_mod(self, config, "flow-mod table=13,cmd=add,prio=113 tunn_id=0x10001,ofdpa_mpls_l2_port=100 write:group=0x91000001 goto:60")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(output_port)+",vlan_vid=0x1003/0x1fff apply:set_field=ofdpa_mpls_l2_port:100,set_field=tunn_id:0x10001 goto:13")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1002/0x1fff goto:20")

+        apply_dpctl_mod(self, config, "flow-mod table=20,cmd=add,prio=201 in_port="+str(input_port)+",vlan_vid=2/0xfff,eth_dst=00:00:04:22:33:55,eth_type=0x00008847 goto:24")

+        apply_dpctl_mod(self, config, "flow-mod table=23,cmd=add,prio=203 eth_type=0x8847,mpls_label=0x903 apply:pop_mpls=0x8847,mpls_dec goto:24")

+        apply_dpctl_mod(self, config, "flow-mod table=24,cmd=add,prio=204 eth_type=0x8847,mpls_label=0x901,mpls_bos=1 apply:pop_mpls=0x8847,mpls_dec,ofdpa_pop_l2hdr,ofdpa_pop_cw,set_field=ofdpa_mpls_l2_port:0x20100,set_field=tunn_id:0x10001 write:group=0x2000"+str(input_port)+" goto:60")

+

+        input_pkt = simple_packet(

+                '00 00 04 22 33 55 00 00 04 22 44 66 81 00 00 02 '

+                '88 47 00 90 3e fa 00 90 1b ff 00 00 00 00 00 00 '

+                '00 11 33 55 00 00 00 11 22 33 81 00 00 05 08 00 '

+                '45 00 00 2e 04 d2 00 00 7f 00 b1 aa c0 a8 02 01 '

+                'c0 a8 02 02 00 01 02 03 04 05 06 07 08 09 0a 0b '

+                '0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19')

+

+        output_pkt = simple_packet(

+                '00 00 00 11 33 55 00 00 00 11 22 33 81 00 00 05 '

+                '08 00 45 00 00 2e 04 d2 00 00 7f 00 b1 aa c0 a8 '

+                '02 01 c0 a8 02 02 00 01 02 03 04 05 06 07 08 09 '

+                '0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+

+

+class decap_penultimate_swap_mpls(base_tests.SimpleDataPlane):

+    """

+    [Penultimate Hop Pop and swap inner MPLS label]

+      Pop outermost tunnel label and swap inner MPLS label (MS-PW, LSR)

+

+    Inject  eth 1/1 Tag 2, Outer label 0x903, InLabel 0x901, SA000004223355, DA000004224466; InTag 5, InSA000000112233, InDA000000113355

+    Output  eth 1/3 Tag 2, Label 0x905, TTL 249, SA000004223355, DA000004224466

+

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20003 group=any,port=any,weight=0 output=3

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x90000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:55,set_field=eth_dst=00:00:04:22:44:66,set_field=vlan_vid=2,group=0x20003

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x91000001 group=any,port=any,weight=0 set_field=mpls_label:0x901,set_field=mpls_tc:7,set_field=ofdpa_mpls_ttl:250,ofdpa_push_l2hdr,push_vlan=0x8100,push_mpls=0x8847,ofdpa_push_cw,group=0x90000001

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=13,cmd=add,prio=113 tunn_id=0x10001,ofdpa_mpls_l2_port=100 write:group=0x91000001 goto:60

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=23,cmd=add,prio=203 eth_type=0x8847,mpls_label=0x903 apply:pop_mpls=0x8847,mpls_dec goto:24

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x95000001 group=any,port=any,weight=0 set_field=mpls_label:0x905,group=0x90000001

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=24,cmd=add,prio=204 eth_type=0x8847,mpls_label=0x901,mpls_bos=1 apply:mpls_dec write:group=0x95000001 goto:60

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=1,vlan_vid=0x1002/0x1fff goto:20

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=20,cmd=add,prio=201 in_port=1,vlan_vid=2/0xfff,eth_dst=00:00:04:22:33:55,eth_type=0x8847 goto:24

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x90000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:55,set_field=eth_dst=00:00:04:22:44:66,set_field=vlan_vid=2,group=0x2000"+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x91000001 group=any,port=any,weight=0 set_field=mpls_label:0x901,set_field=mpls_tc:7,set_field=ofdpa_mpls_ttl:250,ofdpa_push_l2hdr,push_vlan=0x8100,push_mpls=0x8847,ofdpa_push_cw,group=0x90000001")

+        apply_dpctl_mod(self, config, "flow-mod table=13,cmd=add,prio=113 tunn_id=0x10001,ofdpa_mpls_l2_port=100 write:group=0x91000001 goto:60")

+        apply_dpctl_mod(self, config, "flow-mod table=23,cmd=add,prio=203 eth_type=0x8847,mpls_label=0x903 apply:pop_mpls=0x8847,mpls_dec goto:24")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x95000001 group=any,port=any,weight=0 set_field=mpls_label:0x905,group=0x90000001")

+        apply_dpctl_mod(self, config, "flow-mod table=24,cmd=add,prio=204 eth_type=0x8847,mpls_label=0x901,mpls_bos=1 apply:mpls_dec write:group=0x95000001 goto:60")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1002/0x1fff goto:20")

+        apply_dpctl_mod(self, config, "flow-mod table=20,cmd=add,prio=201 in_port="+str(input_port)+",vlan_vid=2/0xfff,eth_dst=00:00:04:22:33:55,eth_type=0x8847 goto:24")

+

+        input_pkt = simple_packet(

+                '00 00 04 22 33 55 00 00 04 22 44 66 81 00 00 02 '

+                '88 47 00 90 3e fa 00 90 1b ff 00 00 00 00 00 00 '

+                '00 11 33 55 00 00 00 11 22 33 81 00 00 05 08 00 '

+                '45 00 00 2e 04 d2 00 00 7f 00 b1 aa c0 a8 02 01 '

+                'c0 a8 02 02 00 01 02 03 04 05 06 07 08 09 0a 0b '

+                '0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19')

+

+        output_pkt = simple_packet(

+                '00 00 04 22 44 66 00 00 04 22 33 55 81 00 00 02 '

+                '88 47 00 90 51 f9 00 00 00 00 00 00 00 11 33 55 '

+                '00 00 00 11 22 33 81 00 00 05 08 00 45 00 00 2e '

+                '04 d2 00 00 7f 00 b1 aa c0 a8 02 01 c0 a8 02 02 '

+                '00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f '

+                '10 11 12 13 14 15 16 17 18 19')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+

+

+

+class swap_out_mpls(base_tests.SimpleDataPlane):

+    """

+    [Swap outermost MPLS label]

+      Swap outermost MPLS label (LSR)

+

+    Inject  eth 1/1 Tag 2, Outer label 0x901, TTL 250, InLabel 0xF, DA000004223355, SA000004224466

+    Output  eth 1/3 Tag 2, Outer label 0x9051, TTL 249, InLabel 0xF, SA000004223357, DA000004224467

+

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20003 group=any,port=any,weight=0 output=3

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x90000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:57,set_field=eth_dst=00:00:04:22:44:67,set_field=vlan_vid=2,group=0x20003

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x95000001 group=any,port=any,weight=0 set_field=mpls_label:0x9051,group=0x90000001

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=24,cmd=add,prio=204 eth_type=0x8847,mpls_label=0x901 apply:mpls_dec write:group=0x95000001 goto:60

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=1,vlan_vid=0x1002/0x1fff goto:20

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=20,cmd=add,prio=201 in_port=1,vlan_vid=2/0xfff,eth_dst=00:00:04:22:33:55,eth_type=0x8847 goto:24

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x90000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:57,set_field=eth_dst=00:00:04:22:44:67,set_field=vlan_vid=2,group=0x2000"+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x95000001 group=any,port=any,weight=0 set_field=mpls_label:0x9051,group=0x90000001")

+        apply_dpctl_mod(self, config, "flow-mod table=24,cmd=add,prio=204 eth_type=0x8847,mpls_label=0x901 apply:mpls_dec write:group=0x95000001 goto:60")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1002/0x1fff goto:20")

+        apply_dpctl_mod(self, config, "flow-mod table=20,cmd=add,prio=201 in_port="+str(input_port)+",vlan_vid=2/0xfff,eth_dst=00:00:04:22:33:55,eth_type=0x8847 goto:24")

+

+        input_pkt = simple_packet(

+                '00 00 04 22 33 55 00 00 04 22 44 66 81 00 00 02 '

+                '88 47 00 90 1e fa 00 01 0b ff 00 00 00 00 00 00 '

+                '00 11 33 55 00 00 00 11 22 33 81 00 00 05 08 00 '

+                '45 00 00 2e 04 d2 00 00 7f 00 b1 aa c0 a8 02 01 '

+                'c0 a8 02 02 00 01 02 03 04 05 06 07 08 09 0a 0b '

+                '0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19')

+

+        output_pkt = simple_packet(

+                '00 00 04 22 44 67 00 00 04 22 33 57 81 00 00 02 '

+                '88 47 09 05 10 f9 00 01 0b ff 00 00 00 00 00 00 '

+                '00 11 33 55 00 00 00 11 22 33 81 00 00 05 08 00 '

+                '45 00 00 2e 04 d2 00 00 7f 00 b1 aa c0 a8 02 01 '

+                'c0 a8 02 02 00 01 02 03 04 05 06 07 08 09 0a 0b '

+                '0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+

+

+

+class swap_encap_mpls(base_tests.SimpleDataPlane):

+    """

+    [Swap and encap a MPLS label]

+      Swap and encap a MPLS label

+

+    Inject  eth 1/1 Tag 2, MPLS label 0x901, TTL 250, DA000004223355, SA000004224466

+    Output  eth 1/3 Tag 2, Outer label 0x9052, TTL 249, InLabel 0xF, SA000004223358, DA000004224468

+

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20003 group=any,port=any,weight=0 output=3

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x90000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:58,set_field=eth_dst=00:00:04:22:44:68,set_field=vlan_vid=2,group=0x20003

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x95000001 group=any,port=any,weight=0 set_field=mpls_label:0x9052,group=0x90000001

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=24,cmd=add,prio=204 eth_type=0x8847,mpls_label=0x901,mpls_bos=1 apply:mpls_dec write:group=0x95000001 goto:60

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=1,vlan_vid=0x1002/0x1fff goto:20

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=20,cmd=add,prio=201 in_port=1,vlan_vid=2/0xfff,eth_dst=00:00:04:22:33:55,eth_type=0x8847 goto:24

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x90000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:58,set_field=eth_dst=00:00:04:22:44:68,set_field=vlan_vid=2,group=0x2000"+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x95000001 group=any,port=any,weight=0 set_field=mpls_label:0x9052,group=0x90000001")

+        apply_dpctl_mod(self, config, "flow-mod table=24,cmd=add,prio=204 eth_type=0x8847,mpls_label=0x901,mpls_bos=1 apply:mpls_dec write:group=0x95000001 goto:60")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1002/0x1fff goto:20")

+        apply_dpctl_mod(self, config, "flow-mod table=20,cmd=add,prio=201 in_port="+str(input_port)+",vlan_vid=2/0xfff,eth_dst=00:00:04:22:33:55,eth_type=0x8847 goto:24")

+

+        input_pkt = simple_packet(

+                '00 00 04 22 33 55 00 00 04 22 44 66 81 00 00 02 '

+                '88 47 00 90 1f fa 00 00 00 00 00 00 00 11 33 55 '

+                '00 00 00 11 22 33 81 00 00 05 08 00 45 00 00 2e '

+                '04 d2 00 00 7f 00 b1 aa c0 a8 02 01 c0 a8 02 02 '

+                '00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f '

+                '10 11 12 13 14 15 16 17 18 19 00 00 00 00')

+

+        output_pkt = simple_packet(

+                '00 00 04 22 44 68 00 00 04 22 33 58 81 00 00 02 '

+                '88 47 09 05 21 f9 00 00 00 00 00 00 00 11 33 55 '

+                '00 00 00 11 22 33 81 00 00 05 08 00 45 00 00 2e '

+                '04 d2 00 00 7f 00 b1 aa c0 a8 02 01 c0 a8 02 02 '

+                '00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f '

+                '10 11 12 13 14 15 16 17 18 19 00 00 00 00')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+

+

+class swap_encap_2mpls(base_tests.SimpleDataPlane):

+    """

+    [Swap and encap 2 MPLS labels]

+      Swap and encap 2 MPLS labels

+

+    Inject  eth 1/1 Tag 2, MPLS label 0x901, TTL 250, DA000004223355, SA000004224466

+    Output  eth 1/3 Tag 2, Outest label 0x904, TTL 249, Middle label 0x903, InLabel 0x9052, SA000004223358, DA000004224468

+

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20003 group=any,port=any,weight=0 output=3

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x90000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:58,set_field=eth_dst=00:00:04:22:44:68,set_field=vlan_vid=2,group=0x20003

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x94000001 group=any,port=any,weight=0 push_mpls=0x8847,set_field=mpls_label:0x904,group=0x90000001

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x93000001 group=any,port=any,weight=0 push_mpls=0x8847,set_field=mpls_label:0x903,group=0x94000001

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x95000001 group=any,port=any,weight=0 set_field=mpls_label:0x9052,group=0x93000001

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=24,cmd=add,prio=204 eth_type=0x8847,mpls_label=0x901,mpls_bos=1 apply:mpls_dec write:group=0x95000001 goto:60

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=1,vlan_vid=0x1002/0x1fff goto:20

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=20,cmd=add,prio=201 in_port=1,vlan_vid=2/0xfff,eth_dst=00:00:04:22:33:55,eth_type=0x8847 goto:24

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x90000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:58,set_field=eth_dst=00:00:04:22:44:68,set_field=vlan_vid=2,group=0x2000"+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x94000001 group=any,port=any,weight=0 push_mpls=0x8847,set_field=mpls_label:0x904,group=0x90000001")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x93000001 group=any,port=any,weight=0 push_mpls=0x8847,set_field=mpls_label:0x903,group=0x94000001")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x95000001 group=any,port=any,weight=0 set_field=mpls_label:0x9052,group=0x93000001")

+        apply_dpctl_mod(self, config, "flow-mod table=24,cmd=add,prio=204 eth_type=0x8847,mpls_label=0x901,mpls_bos=1 apply:mpls_dec write:group=0x95000001 goto:60")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1002/0x1fff goto:20")

+        apply_dpctl_mod(self, config, "flow-mod table=20,cmd=add,prio=201 in_port="+str(input_port)+",vlan_vid=2/0xfff,eth_dst=00:00:04:22:33:55,eth_type=0x8847 goto:24")

+

+        input_pkt = simple_packet(

+                '00 00 04 22 33 55 00 00 04 22 44 66 81 00 00 02 '

+                '88 47 00 90 1f fa 00 00 00 00 00 00 00 11 33 55 '

+                '00 00 00 11 22 33 81 00 00 05 08 00 45 00 00 2e '

+                '04 d2 00 00 7f 00 b1 aa c0 a8 02 01 c0 a8 02 02 '

+                '00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f '

+                '10 11 12 13 14 15 16 17 18 19 00 00 00 00')

+

+        output_pkt = simple_packet(

+                '00 00 04 22 44 68 00 00 04 22 33 58 81 00 00 02 '

+                '88 47 00 90 40 f9 00 90 30 f9 09 05 21 f9 00 00 '

+                '00 00 00 00 00 11 33 55 00 00 00 11 22 33 81 00 '

+                '00 05 08 00 45 00 00 2e 04 d2 00 00 7f 00 b1 aa '

+                'c0 a8 02 01 c0 a8 02 02 00 01 02 03 04 05 06 07 '

+                '08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 '

+                '18 19 00 00 00 00')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+

+

+class decap_1mpls_of3(base_tests.SimpleDataPlane):

+    """

+    [Decap outermost MPLS label of 3 MPLS labels]

+      Decap outermost one MPLS of 3 MPLS labels

+

+    Inject  eth 1/1 Tag 2, Outest label 0x904, TTL 250, Middle label 0x903/250, InLabel 0x901/250, SA000004224466, DA000004223355

+    Output  eth 1/3 Tag 2, Outer label 0x903/249, InLabel 0x901/250, SA000004223355, DA000004224466

+

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20003 group=any,port=any,weight=0 output=3

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x90000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:55,set_field=eth_dst=00:00:04:22:44:66,set_field=vlan_vid=2,group=0x20003

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=24,cmd=add,prio=204 eth_type=0x8847,mpls_label=0x904 apply:pop_mpls=0x8847,mpls_dec write:group=0x90000001 goto:60

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=1,vlan_vid=0x1002/0x1fff goto:20

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=20,cmd=add,prio=201 in_port=1,vlan_vid=2/0xfff,eth_dst=00:00:04:22:33:55,eth_type=0x8847 goto:24

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x90000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:55,set_field=eth_dst=00:00:04:22:44:66,set_field=vlan_vid=2,group=0x2000"+str(output_port))

+        apply_dpctl_mod(self, config, "flow-mod table=24,cmd=add,prio=204 eth_type=0x8847,mpls_label=0x904 apply:pop_mpls=0x8847,mpls_dec write:group=0x90000001 goto:60")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1002/0x1fff goto:20")

+        apply_dpctl_mod(self, config, "flow-mod table=20,cmd=add,prio=201 in_port="+str(input_port)+",vlan_vid=2/0xfff,eth_dst=00:00:04:22:33:55,eth_type=0x8847 goto:24")

+

+        input_pkt = simple_packet(

+                '00 00 04 22 33 55 00 00 04 22 44 66 81 00 00 02 '

+                '88 47 00 90 4e fa 00 90 3e fa 00 90 1f fa 00 00 '

+                '00 00 00 00 00 11 33 55 00 00 00 11 22 33 00 00 '

+                '00 03 08 00 45 00 00 2e 04 d2 00 00 7f 00 b1 aa '

+                'c0 a8 02 01 c0 a8 02 02 00 01 02 03 04 05 06 07 '

+                '08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 '

+                '18 19')

+

+        output_pkt = simple_packet(

+                '00 00 04 22 44 66 00 00 04 22 33 55 81 00 00 02 '

+                '88 47 00 90 3e f9 00 90 1f fa 00 00 00 00 00 00 '

+                '00 11 33 55 00 00 00 11 22 33 00 00 00 03 08 00 '

+                '45 00 00 2e 04 d2 00 00 7f 00 b1 aa c0 a8 02 01 '

+                'c0 a8 02 02 00 01 02 03 04 05 06 07 08 09 0a 0b '

+                '0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+

+

+class decap_2mpls_of3(base_tests.SimpleDataPlane):

+    """

+    [Decap outermost 2 MPLS labels of 3 MPLS labels]

+      Decap outermost two MPLS of 3 MPLS labels

+

+    Inject  eth 1/1 Tag 2, Outest label 0x904, TTL 250, Middle label 0x903/250, InLabel 0x901/250, SA000004224466, DA000004223355

+    Output  eth 1/3 Tag 2, MPLS Label 0x901/249, SA000004223355, DA000004224466

+

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20003 group=any,port=any,weight=0 output=3

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x90000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:55,set_field=eth_dst=00:00:04:22:44:66,set_field=vlan_vid=2,group=0x20003

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=23,cmd=add,prio=203 eth_type=0x8847,mpls_label=0x904 apply:pop_mpls=0x8847,mpls_dec goto:24

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=24,cmd=add,prio=204 eth_type=0x8847,mpls_label=0x903 apply:pop_mpls=0x8847,mpls_dec write:group=0x90000001 goto:60

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=1,vlan_vid=0x1002/0x1fff goto:20

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=20,cmd=add,prio=201 in_port=1,vlan_vid=2/0xfff,eth_dst=00:00:04:22:33:55,eth_type=0x8847 goto:24

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x90000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:55,set_field=eth_dst=00:00:04:22:44:66,set_field=vlan_vid=2,group=0x2000"+str(output_port))

+        apply_dpctl_mod(self, config, "flow-mod table=23,cmd=add,prio=203 eth_type=0x8847,mpls_label=0x904 apply:pop_mpls=0x8847,mpls_dec goto:24")

+        apply_dpctl_mod(self, config, "flow-mod table=24,cmd=add,prio=204 eth_type=0x8847,mpls_label=0x903 apply:pop_mpls=0x8847,mpls_dec write:group=0x90000001 goto:60")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1002/0x1fff goto:20")

+        apply_dpctl_mod(self, config, "flow-mod table=20,cmd=add,prio=201 in_port="+str(input_port)+",vlan_vid=2/0xfff,eth_dst=00:00:04:22:33:55,eth_type=0x8847 goto:24")

+

+        input_pkt = simple_packet(

+                '00 00 04 22 33 55 00 00 04 22 44 66 81 00 00 02 '

+                '88 47 00 90 4e fa 00 90 3e fa 00 90 1f fa 00 00 '

+                '00 00 00 00 00 11 33 55 00 00 00 11 22 33 00 00 '

+                '00 03 08 00 45 00 00 2e 04 d2 00 00 7f 00 b1 aa '

+                'c0 a8 02 01 c0 a8 02 02 00 01 02 03 04 05 06 07 '

+                '08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 '

+                '18 19')

+

+        output_pkt = simple_packet(

+                '00 00 04 22 44 66 00 00 04 22 33 55 81 00 00 02 '

+                '88 47 00 90 1f f9 00 00 00 00 00 00 00 11 33 55 '

+                '00 00 00 11 22 33 00 00 00 03 08 00 45 00 00 2e '

+                '04 d2 00 00 7f 00 b1 aa c0 a8 02 01 c0 a8 02 02 '

+                '00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f '

+                '10 11 12 13 14 15 16 17 18 19')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+

+

+class encap_2mpls_ff(base_tests.SimpleDataPlane):

+    """

+    [Encap two MPLS labels with FF]

+      Encap two MPLS labels with fast failover group

+

+    Env eth 1/1 link up; eth 1/5 link down

+    Inject  eth 1/3 Tag 3, SA000000112233, DA000000113355

+    Output  eth 1/1 Tag 2, Outest label 0x931, TTL 250, InLabel 0x901, SA000004223351, DA000004224461

+

+    Env eth 1/1 link down; eth 1/5 link up

+    Inject  eth 1/3 Tag 3, SA000000112233, DA000000113355

+    Output  eth 1/5 Tag 2, Outest label 0x935, TTL 250, InLabel 0x901, SA000004223355, DA000004224465

+

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20001 group=any,port=any,weight=0 output=1

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x90000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:51,set_field=eth_dst=00:00:04:22:44:61,set_field=vlan_vid=2,group=0x20001

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x93000001 group=any,port=any,weight=0 push_mpls=0x8847,set_field=mpls_label:0x931,group=0x90000001

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20005 group=any,port=any,weight=0 output=5

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x90000005 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:55,set_field=eth_dst=00:00:04:22:44:65,set_field=vlan_vid=2,group=0x20005

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x93000005 group=any,port=any,weight=0 push_mpls=0x8847,set_field=mpls_label:0x935,group=0x90000005

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ff,group=0xA6000001 group=any,port=1,weight=0 group=0x93000001 group=any,port=5,weight=0 group=0x93000005

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x91000001 group=any,port=any,weight=0 set_field=mpls_label:0x901,set_field=mpls_tc:7,set_field=ofdpa_mpls_ttl:250,ofdpa_push_l2hdr,push_vlan=0x8100,push_mpls=0x8847,ofdpa_push_cw,group=0xA6000001

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=13,cmd=add,prio=113 tunn_id=0x10001,ofdpa_mpls_l2_port=100 write:group=0x91000001 goto:60

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=3,vlan_vid=0x1003/0x1fff apply:set_field=ofdpa_mpls_l2_port:100,set_field=tunn_id:0x10001 goto:13

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=24,cmd=add,prio=204 eth_type=0x8847,mpls_label=0x901,mpls_bos=1 apply:pop_mpls=0x8847,mpls_dec,ofdpa_pop_l2hdr,ofdpa_pop_cw,set_field=ofdpa_mpls_l2_port:0x20100,set_field=tunn_id:0x10001 write:group=0x20001 goto:60

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+        output_port2 = test_ports[2]

+        

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x90000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:51,set_field=eth_dst=00:00:04:22:44:61,set_field=vlan_vid=2,group=0x2000"+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x93000001 group=any,port=any,weight=0 push_mpls=0x8847,set_field=mpls_label:0x931,group=0x90000001")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(output_port2)+" group=any,port=any,weight=0 output="+str(output_port2))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x90000005 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:55,set_field=eth_dst=00:00:04:22:44:65,set_field=vlan_vid=2,group=0x2000"+str(output_port2))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x93000005 group=any,port=any,weight=0 push_mpls=0x8847,set_field=mpls_label:0x935,group=0x90000005")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ff,group=0xA6000001 group=any,port="+str(output_port)+",weight=0 group=0x93000001 group=any,port="+str(output_port2)+",weight=0 group=0x93000005")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x91000001 group=any,port=any,weight=0 set_field=mpls_label:0x901,set_field=mpls_tc:7,set_field=ofdpa_mpls_ttl:250,ofdpa_push_l2hdr,push_vlan=0x8100,push_mpls=0x8847,ofdpa_push_cw,group=0xA6000001")

+        apply_dpctl_mod(self, config, "flow-mod table=13,cmd=add,prio=113 tunn_id=0x10001,ofdpa_mpls_l2_port=100 write:group=0x91000001 goto:60")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1003/0x1fff apply:set_field=ofdpa_mpls_l2_port:100,set_field=tunn_id:0x10001 goto:13")

+        apply_dpctl_mod(self, config, "flow-mod table=24,cmd=add,prio=204 eth_type=0x8847,mpls_label=0x901,mpls_bos=1 apply:pop_mpls=0x8847,mpls_dec,ofdpa_pop_l2hdr,ofdpa_pop_cw,set_field=ofdpa_mpls_l2_port:0x20100,set_field=tunn_id:0x10001 write:group=0x2000"+str(output_port)+" goto:60")

+

+        input_pkt = simple_packet(

+                '00 00 00 11 33 55 00 00 00 11 22 33 81 00 00 03 '

+                '08 00 45 00 00 2e 04 d2 00 00 7f 00 b2 47 c0 a8 '

+                '01 64 c0 a8 02 02 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        output_pkt = simple_packet(

+                '00 00 04 22 44 61 00 00 04 22 33 51 81 00 00 02 '

+                '88 47 00 93 1e fa 00 90 1f fa 00 00 00 00 00 00 '

+                '00 11 33 55 00 00 00 11 22 33 81 00 00 03 08 00 '

+                '45 00 00 2e 04 d2 00 00 7f 00 b2 47 c0 a8 01 64 '

+                'c0 a8 02 02 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        output_pkt2 = simple_packet(

+                '00 00 04 22 44 65 00 00 04 22 33 55 81 00 00 02 '

+                '88 47 00 93 5e fa 00 90 1f fa 00 00 00 00 00 00 '

+                '00 11 33 55 00 00 00 11 22 33 81 00 00 03 08 00 '

+                '45 00 00 2e 04 d2 00 00 7f 00 b2 47 c0 a8 01 64 '

+                'c0 a8 02 02 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+

+        #if output_port link down

+        apply_dpctl_mod(self, config, "port-mod port="+str(output_port)+",conf=0x1,mask=0x1")

+        time.sleep(1)

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt2), output_port2)

+        apply_dpctl_mod(self, config, "port-mod port="+str(output_port)+",conf=0x0,mask=0x1")

+        #make sure port link up        

+        port_up = 0

+        while port_up == 0:

+            time.sleep(1)

+            #apply_dpctl_mod(self, config, "port-mod port="+str(output_port)+",conf=0x0,mask=0x1")

+            json_result = apply_dpctl_get_cmd(self, config, "port-desc")

+            result=json_result["RECEIVED"][1]

+            for p_desc in result["port"]:

+                if p_desc["no"] == output_port:

+                    if p_desc["config"] != 0x01 : #up                        

+                        port_up = 1

+                                

+

+

+class decap_mpls_acl(base_tests.SimpleDataPlane):

+    """

+    [Decap a MPLS label with ACL]

+      Decap a MPLS label with ACL

+

+    Inject  eth 1/1 Tag 2, SA000004223355, DA000004224466, MPLS label 2305, EXP7, BoS1, TTL250, CW, InSA000000112233, InDA000000113355

+    Output  eth 1/5 SA000000112233, DA000000113355

+

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20001 group=any,port=any,weight=0 output=1

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=24,cmd=add,prio=204 eth_type=0x8847,mpls_label=0x901,mpls_bos=1 apply:pop_mpls=0x8847,mpls_dec,ofdpa_pop_l2hdr,ofdpa_pop_cw,set_field=ofdpa_mpls_l2_port:0x20100,set_field=tunn_id:0x10001 write:group=0x20001 goto:60

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x90000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:55,set_field=eth_dst=00:00:04:22:44:66,set_field=vlan_vid=2,group=0x20001

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x91000001 group=any,port=any,weight=0 set_field=mpls_label:0x901,set_field=mpls_tc:7,set_field=ofdpa_mpls_ttl:250,ofdpa_push_l2hdr,push_vlan=0x8100,push_mpls=0x8847,ofdpa_push_cw,group=0x90000001

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=13,cmd=add,prio=113 tunn_id=0x10001,ofdpa_mpls_l2_port=100 write:group=0x91000001 goto:60

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=3 apply:set_field=ofdpa_mpls_l2_port:100,set_field=tunn_id:0x10001 goto:13

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=1,vlan_vid=0x1002/0x1fff goto:20

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=20,cmd=add,prio=201 in_port=1,vlan_vid=2/0xfff,eth_dst=00:00:04:22:33:55,eth_type=0x8847 goto:24

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20005 group=any,port=any,weight=0 output=5

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=60,cmd=add,prio=601 tunn_id=0x10001,ofdpa_mpls_l2_port=131328 write:group=0x20005

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(input_port)+" group=any,port=any,weight=0 output="+str(input_port))

+        apply_dpctl_mod(self, config, "flow-mod table=24,cmd=add,prio=204 eth_type=0x8847,mpls_label=0x901,mpls_bos=1 apply:pop_mpls=0x8847,mpls_dec,ofdpa_pop_l2hdr,ofdpa_pop_cw,set_field=ofdpa_mpls_l2_port:0x20100,set_field=tunn_id:0x10001 write:group=0x2000"+str(input_port)+" goto:60")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x90000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:55,set_field=eth_dst=00:00:04:22:44:66,set_field=vlan_vid=2,group=0x2000"+str(input_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x91000001 group=any,port=any,weight=0 set_field=mpls_label:0x901,set_field=mpls_tc:7,set_field=ofdpa_mpls_ttl:250,ofdpa_push_l2hdr,push_vlan=0x8100,push_mpls=0x8847,ofdpa_push_cw,group=0x90000001")

+        apply_dpctl_mod(self, config, "flow-mod table=13,cmd=add,prio=113 tunn_id=0x10001,ofdpa_mpls_l2_port=100 write:group=0x91000001 goto:60")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+" apply:set_field=ofdpa_mpls_l2_port:100,set_field=tunn_id:0x10001 goto:13")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1002/0x1fff goto:20")

+        apply_dpctl_mod(self, config, "flow-mod table=20,cmd=add,prio=201 in_port="+str(input_port)+",vlan_vid=2/0xfff,eth_dst=00:00:04:22:33:55,eth_type=0x8847 goto:24")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "flow-mod table=60,cmd=add,prio=601 tunn_id=0x10001,ofdpa_mpls_l2_port=131328 write:group=0x2000"+str(output_port))

+

+        input_pkt = simple_packet(

+                '00 00 04 22 33 55 00 00 04 22 44 66 81 00 00 02 '

+                '88 47 00 90 1f fa 00 00 00 00 00 00 00 11 33 55 '

+                '00 00 00 11 22 33 81 00 00 05 08 00 45 00 00 2e '

+                '04 d2 00 00 7f 00 b1 aa c0 a8 02 01 c0 a8 02 02 '

+                '00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f '

+                '10 11 12 13 14 15 16 17 18 19 00 00 00 00')

+

+        output_pkt = simple_packet(

+                '00 00 00 11 33 55 00 00 00 11 22 33 81 00 00 05 '

+                '08 00 45 00 00 2e 04 d2 00 00 7f 00 b1 aa c0 a8 '

+                '02 01 c0 a8 02 02 00 01 02 03 04 05 06 07 08 09 '

+                '0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 '

+                '00 00 00 00')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+

+

+class encap_mpls_l3(base_tests.SimpleDataPlane):

+    """

+    [Encap a MPLS label with L3]

+      Encap a MPLS label with L3 routing

+

+    Inject  eth 1/3 Tag 2, SA000000112233, DA000000113355, SIP 192.168.1.10, DIP 192.168.2.2

+    Output  eth 1/1 SA000004223355, DA000004224466, Tag2, MPLS label 0x901; IP the same as original

+

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=0,cmd=add,prio=1 in_port=0/0xffff0000 goto:10

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=3,vlan_vid=0x1002/0x1fff goto:20

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=20,cmd=add,prio=201 in_port=3,vlan_vid=2/0xfff,eth_dst=00:00:00:11:33:55,eth_type=0x0800 goto:30

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20001 group=any,port=any,weight=0 output=1

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x90000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:55,set_field=eth_dst=00:00:04:22:44:66,set_field=vlan_vid=2,group=0x20001

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x92000001 group=any,port=any,weight=0 set_field=mpls_label:0x901,set_field=mpls_tc:7,set_field=ofdpa_mpls_ttl:250,ttl_out,group=0x90000001

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=30,cmd=add,prio=301 eth_type=0x0800,ip_dst=192.168.2.2/255.255.255.0 write:group=0x92000001 goto:60

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "flow-mod table=0,cmd=add,prio=1 in_port=0/0xffff0000 goto:10")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1002/0x1fff goto:20")

+        apply_dpctl_mod(self, config, "flow-mod table=20,cmd=add,prio=201 in_port="+str(input_port)+",vlan_vid=2/0xfff,eth_dst=00:00:00:11:33:55,eth_type=0x0800 goto:30")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x90000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:55,set_field=eth_dst=00:00:04:22:44:66,set_field=vlan_vid=2,group=0x2000"+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x92000001 group=any,port=any,weight=0 set_field=mpls_label:0x901,set_field=mpls_tc:7,set_field=ofdpa_mpls_ttl:250,ttl_out,group=0x90000001")

+        apply_dpctl_mod(self, config, "flow-mod table=30,cmd=add,prio=301 eth_type=0x0800,ip_dst=192.168.2.2/255.255.255.0 write:group=0x92000001 goto:60")

+

+        input_pkt = simple_packet(

+                '00 00 00 11 33 55 00 00 00 11 22 33 81 00 00 02 '

+                '08 00 45 00 00 4e 04 d2 00 00 7f 00 b0 81 c0 a8 '

+                '03 0a c0 a8 02 02 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        output_pkt = simple_packet(

+                '00 00 04 22 44 66 00 00 04 22 33 55 81 00 00 02 '

+                '88 47 00 90 1f fa 45 00 00 4e 04 d2 00 00 7e 00 '

+                'b1 81 c0 a8 03 0a c0 a8 02 02 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+

+

+class decap_mpls_l3(base_tests.SimpleDataPlane):

+    """

+    [Decap a MPLS label with L3]

+      Decap a MPLS label with L3 routing

+

+    Inject  eth 1/3 Tag 12, SA000000112233, DA000000000111, MPLS 0x1234, SIP 192.168.3.1, DIP 192.168.2.1

+    Output  eth 1/1 Tag 10, SA000006223355, DA000006224466, SIP 192.168.3.1, DIP 192.168.2.1

+

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=3,vlan_vid=0x100c/0x1fff apply:set_field=ofdpa_vrf:1 goto:20

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0xa0001 group=any,port=any,weight=0 output=1

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20000001 group=any,port=any,weight=0 set_field=eth_src=00:00:06:22:33:55,set_field=eth_dst=00:00:06:22:44:66,set_field=vlan_vid=10,group=0xa0001

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=24,cmd=add,prio=204 eth_type=0x8847,mpls_label=0x1234,mpls_bos=1,ofdpa_mpls_data_first_nibble=4 apply:mpls_dec,pop_mpls=0x0800,set_field=ofdpa_vrf:1 goto:30

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=30,cmd=add,prio=301 eth_type=0x0800,ip_dst=192.168.3.2/255.255.255.0,ofdpa_vrf=1 write:group=0x20000001 goto:60

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=20,cmd=add,prio=201 vlan_vid=12/0xfff,eth_dst=00:00:00:00:01:11,eth_type=0x8847 goto:24

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x100c/0x1fff apply:set_field=ofdpa_vrf:1 goto:20")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0xa000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x20000001 group=any,port=any,weight=0 set_field=eth_src=00:00:06:22:33:55,set_field=eth_dst=00:00:06:22:44:66,set_field=vlan_vid=10,group=0xa000"+str(output_port))

+        apply_dpctl_mod(self, config, "flow-mod table=24,cmd=add,prio=204 eth_type=0x8847,mpls_label=0x1234,mpls_bos=1,ofdpa_mpls_data_first_nibble=4 apply:mpls_dec,pop_mpls=0x0800,set_field=ofdpa_vrf:1 goto:30")

+        apply_dpctl_mod(self, config, "flow-mod table=30,cmd=add,prio=301 eth_type=0x0800,ip_dst=192.168.3.2/255.255.255.0,ofdpa_vrf=1 write:group=0x20000001 goto:60")

+        apply_dpctl_mod(self, config, "flow-mod table=20,cmd=add,prio=201 vlan_vid=12/0xfff,eth_dst=00:00:00:00:01:11,eth_type=0x8847 goto:24")

+

+        input_pkt = simple_packet(

+                '00 00 00 00 01 11 00 00 00 11 22 33 81 00 00 0c '

+                '88 47 01 23 41 3f 45 00 00 26 00 00 00 00 3f 00 '

+                'f5 84 c0 a8 02 01 c0 a8 03 02 00 01 02 03 04 05 '

+                '06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 '

+                '16 17 18 19')

+

+        output_pkt = simple_packet(

+                '00 00 06 22 44 66 00 00 06 22 33 55 81 00 00 0a '

+                '08 00 45 00 00 26 00 00 00 00 3e 00 f6 84 c0 a8 '

+                '02 01 c0 a8 03 02 00 01 02 03 04 05 06 07 08 09 '

+                '0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+

+

+class encap_2mpls_l3(base_tests.SimpleDataPlane):

+    """

+    [Encap two MPLS labels with L3]

+      Encap two MPLS labels with L3 routing

+

+    Inject  eth 1/3 Tag 2, SA000000112233, DA000000113355, SIP 192.168.1.10, DIP 192.168.2.2

+    Output  eth 1/1 SA000004223355, DA000004224466, Tag2, Outer Label 0x903, EXP 7, TTL 250, Inner Label 0x901, EXP 7, TTL 250; IP the same as original

+

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=0,cmd=add,prio=1 in_port=0/0xffff0000 goto:10

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=3,vlan_vid=0x1002/0x1fff goto:20

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=20,cmd=add,prio=201 in_port=3,vlan_vid=2/0xfff,eth_dst=00:00:00:11:33:55,eth_type=0x0800 goto:30

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20001 group=any,port=any,weight=0 output=1

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x90000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:55,set_field=eth_dst=00:00:04:22:44:66,set_field=vlan_vid=2,group=0x20001

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x93000001 group=any,port=any,weight=0 set_field=mpls_label:0x903,push_mpls=0x8847,group=0x90000001

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x92000001 group=any,port=any,weight=0 set_field=mpls_label:0x901,set_field=mpls_tc:7,set_field=ofdpa_mpls_ttl:250,ttl_out,group=0x93000001

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=30,cmd=add,prio=301 eth_type=0x0800,ip_dst=192.168.2.2/255.255.255.0 write:group=0x92000001 goto:60

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "flow-mod table=0,cmd=add,prio=1 in_port=0/0xffff0000 goto:10")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1002/0x1fff goto:20")

+        apply_dpctl_mod(self, config, "flow-mod table=20,cmd=add,prio=201 in_port="+str(input_port)+",vlan_vid=2/0xfff,eth_dst=00:00:00:11:33:55,eth_type=0x0800 goto:30")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x90000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:55,set_field=eth_dst=00:00:04:22:44:66,set_field=vlan_vid=2,group=0x2000"+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x93000001 group=any,port=any,weight=0 set_field=mpls_label:0x903,push_mpls=0x8847,group=0x90000001")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x92000001 group=any,port=any,weight=0 set_field=mpls_label:0x901,set_field=mpls_tc:7,set_field=ofdpa_mpls_ttl:250,ttl_out,group=0x93000001")

+        apply_dpctl_mod(self, config, "flow-mod table=30,cmd=add,prio=301 eth_type=0x0800,ip_dst=192.168.2.2/255.255.255.0 write:group=0x92000001 goto:60")

+

+        input_pkt = simple_packet(

+                '00 00 00 11 33 55 00 00 00 11 22 33 81 00 00 02 '

+                '08 00 45 00 00 4e 04 d2 00 00 7f 00 b0 81 c0 a8 '

+                '03 0a c0 a8 02 02 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        output_pkt = simple_packet(

+                '00 00 04 22 44 66 00 00 04 22 33 55 81 00 00 02 '

+                '88 47 00 90 3e fa 00 90 1f fa 45 00 00 4e 04 d2 '

+                '00 00 7e 00 b1 81 c0 a8 03 0a c0 a8 02 02 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+

+

+class decap_2mpls_l3(base_tests.SimpleDataPlane):

+    """

+    [Decap two MPLS labels with L3]

+      Decap two MPLS labels with L3 routing

+

+    Inject  eth 1/1 SA000004223355, DA000004224466, Tag2, Outer Label 0x903, EXP 7, TTL 250, Inner Label 0x901, SIP 192.168.3.2, DIP 192.168.2.10

+    Output  eth 1/3 SA000006223355, DA000006224466, Tag2, SIP 192.168.3.2, DIP 192.168.2.10

+

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20003 group=any,port=any,weight=0 output=3

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20000003 group=any,port=any,weight=0 set_field=eth_src=00:00:06:22:33:55,set_field=eth_dst=00:00:06:22:44:66,set_field=vlan_vid=2,group=0x20003

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=1,vlan_vid=0x1002/0x1fff apply:set_field=ofdpa_vrf:1 goto:20

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=20,cmd=add,prio=201 vlan_vid=2/0xfff,eth_dst=00:00:04:22:33:55,eth_type=0x8847 goto:24

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=23,cmd=add,prio=203 eth_type=0x8847,mpls_label=0x903 apply:pop_mpls=0x8847,mpls_dec goto:24

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=24,cmd=add,prio=204 eth_type=0x8847,mpls_label=0x901,mpls_bos=1,ofdpa_mpls_data_first_nibble=4 apply:mpls_dec,pop_mpls=0x0800,set_field=ofdpa_vrf:1 goto:30

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=30,cmd=add,prio=301 eth_type=0x0800,ip_dst=192.168.2.2/255.255.255.0,ofdpa_vrf=1 write:group=0x20000003 goto:60

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x20000003 group=any,port=any,weight=0 set_field=eth_src=00:00:06:22:33:55,set_field=eth_dst=00:00:06:22:44:66,set_field=vlan_vid=2,group=0x2000"+str(output_port))

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1002/0x1fff apply:set_field=ofdpa_vrf:1 goto:20")

+        apply_dpctl_mod(self, config, "flow-mod table=20,cmd=add,prio=201 vlan_vid=2/0xfff,eth_dst=00:00:04:22:33:55,eth_type=0x8847 goto:24")

+        apply_dpctl_mod(self, config, "flow-mod table=23,cmd=add,prio=203 eth_type=0x8847,mpls_label=0x903 apply:pop_mpls=0x8847,mpls_dec goto:24")

+        apply_dpctl_mod(self, config, "flow-mod table=24,cmd=add,prio=204 eth_type=0x8847,mpls_label=0x901,mpls_bos=1,ofdpa_mpls_data_first_nibble=4 apply:mpls_dec,pop_mpls=0x0800,set_field=ofdpa_vrf:1 goto:30")

+        apply_dpctl_mod(self, config, "flow-mod table=30,cmd=add,prio=301 eth_type=0x0800,ip_dst=192.168.2.2/255.255.255.0,ofdpa_vrf=1 write:group=0x20000003 goto:60")

+

+        input_pkt = simple_packet(

+                '00 00 04 22 33 55 00 00 04 22 44 66 81 00 00 02 '

+                '88 47 00 90 3e fa 00 90 1f fa 45 00 00 26 00 00 '

+                '00 00 7e 06 b6 75 c0 a8 03 02 c0 a8 02 0a 00 03 '

+                '00 06 00 01 f7 fa 00 00 00 00 50 00 04 00 2f 5d '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00')

+

+        output_pkt = simple_packet(

+                '00 00 06 22 44 66 00 00 06 22 33 55 81 00 00 02 '

+                '08 00 45 00 00 26 00 00 00 00 f9 06 3b 75 c0 a8 '

+                '03 02 c0 a8 02 0a 00 03 00 06 00 01 f7 fa 00 00 '

+                '00 00 50 00 04 00 2f 5d 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+

+

+class encap_3mpls_l3(base_tests.SimpleDataPlane):

+    """

+    [Encap 3 MPLS labels with L3]

+      Encap 3 MPLS labels with L3 routing

+

+    Inject  eth 1/3 Tag 2, SA000000112233, DA000000113355, SIP 192.168.1.10, DIP 192.168.2.2

+    Output  eth 1/1 SA000004223355, DA000004224466, Tag2, OuterLabel 0x904 EXP 7, TTL 250, M 0x903, Inner0x901, EXP 7, TTL 250; IP the same as original

+

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=0,cmd=add,prio=1 in_port=0/0xffff0000 goto:10

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=3,vlan_vid=0x1002/0x1fff goto:20

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=20,cmd=add,prio=201 in_port=3,vlan_vid=2/0xfff,eth_dst=00:00:00:11:33:55,eth_type=0x0800 goto:30

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20001 group=any,port=any,weight=0 output=1

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x90000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:55,set_field=eth_dst=00:00:04:22:44:66,set_field=vlan_vid=2,group=0x20001

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x94000001 group=any,port=any,weight=0 push_mpls=0x8847,set_field=mpls_label:0x904,group=0x90000001

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x93000001 group=any,port=any,weight=0 set_field=mpls_label:0x903,push_mpls=0x8847,group=0x94000001

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x92000001 group=any,port=any,weight=0 set_field=mpls_label:0x901,set_field=mpls_tc:7,set_field=ofdpa_mpls_ttl:250,ttl_out,group=0x93000001

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=30,cmd=add,prio=301 eth_type=0x0800,ip_dst=192.168.2.2/255.255.255.0 write:group=0x92000001 goto:60

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "flow-mod table=0,cmd=add,prio=1 in_port=0/0xffff0000 goto:10")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1002/0x1fff goto:20")

+        apply_dpctl_mod(self, config, "flow-mod table=20,cmd=add,prio=201 in_port="+str(input_port)+",vlan_vid=2/0xfff,eth_dst=00:00:00:11:33:55,eth_type=0x0800 goto:30")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x90000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:55,set_field=eth_dst=00:00:04:22:44:66,set_field=vlan_vid=2,group=0x2000"+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x94000001 group=any,port=any,weight=0 push_mpls=0x8847,set_field=mpls_label:0x904,group=0x90000001")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x93000001 group=any,port=any,weight=0 set_field=mpls_label:0x903,push_mpls=0x8847,group=0x94000001")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x92000001 group=any,port=any,weight=0 set_field=mpls_label:0x901,set_field=mpls_tc:7,set_field=ofdpa_mpls_ttl:250,ttl_out,group=0x93000001")

+        apply_dpctl_mod(self, config, "flow-mod table=30,cmd=add,prio=301 eth_type=0x0800,ip_dst=192.168.2.2/255.255.255.0 write:group=0x92000001 goto:60")

+

+        input_pkt = simple_packet(

+                '00 00 00 11 33 55 00 00 00 11 22 33 81 00 00 02 '

+                '08 00 45 00 00 4e 04 d2 00 00 7f 00 b0 81 c0 a8 '

+                '03 0a c0 a8 02 02 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        output_pkt = simple_packet(

+                '00 00 04 22 44 66 00 00 04 22 33 55 81 00 00 02 '

+                '88 47 00 90 4e fa 00 90 3e fa 00 90 1f fa 45 00 '

+                '00 4e 04 d2 00 00 7e 00 b1 81 c0 a8 03 0a c0 a8 '

+                '02 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+

diff --git a/Fabric/Utilities/acctonUseDpctl/nat.py b/Fabric/Utilities/acctonUseDpctl/nat.py
new file mode 100755
index 0000000..04f267a
--- /dev/null
+++ b/Fabric/Utilities/acctonUseDpctl/nat.py
@@ -0,0 +1,400 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+import logging

+import oftest.base_tests as base_tests

+from oftest import config

+from oftest.testutils import *

+from util import *

+from accton_util import convertIP4toStr as toIpV4Str

+from accton_util import convertMACtoStr as toMacStr

+

+

+class dnat(base_tests.SimpleDataPlane):

+    """

+    [DNAT]

+      DNAT (inbound)

+

+    Inject  eth 1/3 DA000000000200, SA000000000201, Tag 200, SIP 200.0.0.1, DIP 100.0.0.01, Sport 2828, Dport 5000

+    Output  eth 1/1 DA000000000101, SA000000000100, Tag 100, SIP 200.0.0.1, DIP 10.0.0.01, Sport 2828, Dport 2000

+

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=3,vlan_vid=0x10c8/0x1fff goto:20

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x640001 group=any,port=any,weight=0 output=1

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x23000001 group=any,port=any,weight=0 set_field=eth_src=00:00:00:00:01:00,set_field=eth_dst=00:00:00:00:01:01,set_field=vlan_vid=100,group=0x640001

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=20,cmd=add,prio=201 vlan_vid=200/0xfff,eth_dst=00:00:00:00:02:00,eth_type=0x0800 goto:28

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=28,cmd=add,prio=281 eth_type=0x800,ip_dst=100.0.0.1,ip_proto=6,tcp_dst=5000 write:set_field=ip_dst:10.0.0.1,set_field=tcp_dst:2000,group=0x23000001 goto:60

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x10c8/0x1fff goto:20")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x64000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x23000001 group=any,port=any,weight=0 set_field=eth_src=00:00:00:00:01:00,set_field=eth_dst=00:00:00:00:01:01,set_field=vlan_vid=100,group=0x64000"+str(output_port))

+        apply_dpctl_mod(self, config, "flow-mod table=20,cmd=add,prio=201 vlan_vid=200/0xfff,eth_dst=00:00:00:00:02:00,eth_type=0x0800 goto:28")

+        apply_dpctl_mod(self, config, "flow-mod table=28,cmd=add,prio=281 eth_type=0x800,ip_dst=100.0.0.1,ip_proto=6,tcp_dst=5000 write:set_field=ip_dst:10.0.0.1,set_field=tcp_dst:2000,group=0x23000001 goto:60")

+

+        input_pkt = simple_packet(

+                '00 00 00 00 02 00 00 00 00 00 02 01 81 00 00 c8 '

+                '08 00 45 00 00 2a 04 d2 00 00 7f 06 0a fa c8 00 '

+                '00 01 64 00 00 01 0b 0c 13 88 00 01 f7 fa 00 00 '

+                '00 00 50 00 04 00 69 50 00 00 00 00')

+

+        output_pkt = simple_packet(

+                '00 00 00 00 01 01 00 00 00 00 01 00 81 00 00 64 '

+                '08 00 45 00 00 2a 04 d2 00 00 7e 06 65 fa c8 00 '

+                '00 01 0a 00 00 01 0b 0c 07 d0 00 01 f7 fa 00 00 '

+                '00 00 50 00 04 00 cf 08 00 00 00 00')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+

+

+class dnat_vrf(base_tests.SimpleDataPlane):

+    """

+    [DNAT VRF]

+      DNAT (inbound) with specified VRF

+

+    Inject  eth 1/3 DA000000000200, SA000000000201, Tag 200, SIP 200.0.0.1, DIP 100.0.0.01, Sport 2828, Dport 5000

+    Output  eth 1/1 DA000000000101, SA000000000100, Tag 100, SIP 200.0.0.1, DIP 10.0.0.01, Sport 2828, Dport 2000

+

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=3,vlan_vid=0x10c8/0x1fff goto:20 apply:set_field=ofdpa_vrf:3

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=1,vlan_vid=0x1064/0x1fff goto:20 apply:set_field=ofdpa_vrf:3

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x640001 group=any,port=any,weight=0 output=1

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x23000001 group=any,port=any,weight=0 set_field=eth_src=00:00:00:00:01:00,set_field=eth_dst=00:00:00:00:01:01,set_field=vlan_vid=100,group=0x640001

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=20,cmd=add,prio=201 vlan_vid=200/0xfff,eth_dst=00:00:00:00:02:00,eth_type=0x0800 goto:28

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=28,cmd=add,prio=281 eth_type=0x800,ip_dst=100.0.0.1,ip_proto=6,tcp_dst=5000,ofdpa_vrf=3 write:set_field=ip_dst:10.0.0.1,set_field=tcp_dst:2000,group=0x23000001 goto:60

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x10c8/0x1fff goto:20 apply:set_field=ofdpa_vrf:3")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(output_port)+",vlan_vid=0x1064/0x1fff goto:20 apply:set_field=ofdpa_vrf:3")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x64000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x23000001 group=any,port=any,weight=0 set_field=eth_src=00:00:00:00:01:00,set_field=eth_dst=00:00:00:00:01:01,set_field=vlan_vid=100,group=0x64000"+str(output_port))

+        apply_dpctl_mod(self, config, "flow-mod table=20,cmd=add,prio=201 vlan_vid=200/0xfff,eth_dst=00:00:00:00:02:00,eth_type=0x0800 goto:28")

+        apply_dpctl_mod(self, config, "flow-mod table=28,cmd=add,prio=281 eth_type=0x800,ip_dst=100.0.0.1,ip_proto=6,tcp_dst=5000,ofdpa_vrf=3 write:set_field=ip_dst:10.0.0.1,set_field=tcp_dst:2000,group=0x23000001 goto:60")

+

+        input_pkt = simple_packet(

+                '00 00 00 00 02 00 00 00 00 00 02 01 81 00 00 c8 '

+                '08 00 45 00 00 2a 04 d2 00 00 7f 06 0a fa c8 00 '

+                '00 01 64 00 00 01 0b 0c 13 88 00 01 f7 fa 00 00 '

+                '00 00 50 00 04 00 69 50 00 00 00 00')

+

+        output_pkt = simple_packet(

+                '00 00 00 00 01 01 00 00 00 00 01 00 81 00 00 64 '

+                '08 00 45 00 00 2a 04 d2 00 00 7e 06 65 fa c8 00 '

+                '00 01 0a 00 00 01 0b 0c 07 d0 00 01 f7 fa 00 00 '

+                '00 00 50 00 04 00 cf 08 00 00 00 00')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+

+"""

+currently this case will fail, due to packet rx SRC IP problem

+"""

+class dnat_ecmp(base_tests.SimpleDataPlane):

+    """

+    [DNAT ECMP]

+      DNAT (inbound) with ECMP

+

+    Inject  eth 1/3 DA000000000200, SA000000000201, Tag 200, SIP 200.0.0.1, DIP 100.0.0.01, Sport 2828, Dport 5000 [increase SIP]

+    Output  eth 1/1 DA000000000101, SA000000000100, Tag 100, SIP 200.0.0.X, DIP 10.0.0.01, Sport 2828, Dport 2000

+    Output  eth 1/5 DA000005224466, SA000005223355, Tag 2, SIP 200.0.0.X, DIP 10.0.0.01, Sport 2828, Dport 2000

+

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=3,vlan_vid=0x10c8/0x1fff goto:20

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x640001 group=any,port=any,weight=0 output=1

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x23000001 group=any,port=any,weight=0 set_field=eth_src=00:00:00:00:01:00,set_field=eth_dst=00:00:00:00:01:01,set_field=vlan_vid=100,group=0x640001

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20005 group=any,port=any,weight=0 output=5

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x23000005 group=any,port=any,weight=0 set_field=eth_src=00:00:05:22:33:55,set_field=eth_dst=00:00:05:22:44:66,set_field=vlan_vid=2,group=0x20005

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=sel,group=0x71000001 group=any,port=any,weight=0 group=0x23000001 group=any,port=any,weight=0 group=0x23000005

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=20,cmd=add,prio=201 vlan_vid=200/0xfff,eth_dst=00:00:00:00:02:00,eth_type=0x0800 goto:28

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=28,cmd=add,prio=281 eth_type=0x800,ip_dst=100.0.0.1,ip_proto=6,tcp_dst=5000 write:set_field=ip_dst:10.0.0.1,set_field=tcp_dst:2000,group=0x71000001 goto:60

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+        output_port2 = test_ports[2]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x10c8/0x1fff goto:20 apply:set_field=ofdpa_vrf:3")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x64000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x23000001 group=any,port=any,weight=0 set_field=eth_src=00:00:00:00:01:00,set_field=eth_dst=00:00:00:00:01:01,set_field=vlan_vid=100,group=0x64000"+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(output_port2)+" group=any,port=any,weight=0 output="+str(output_port2))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x23000005 group=any,port=any,weight=0 set_field=eth_src=00:00:05:22:33:55,set_field=eth_dst=00:00:05:22:44:66,set_field=vlan_vid=2,group=0x2000"+str(output_port2))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=sel,group=0x71000001 group=any,port=any,weight=0 group=0x23000001 group=any,port=any,weight=0 group=0x23000005")

+        apply_dpctl_mod(self, config, "flow-mod table=20,cmd=add,prio=201 vlan_vid=200/0xfff,eth_dst=00:00:00:00:02:00,eth_type=0x0800 goto:28")

+        apply_dpctl_mod(self, config, "flow-mod table=28,cmd=add,prio=281 eth_type=0x800,ip_dst=100.0.0.1,ip_proto=6,tcp_dst=5000 write:set_field=ip_dst:10.0.0.1,set_field=tcp_dst:2000,group=0x71000001 goto:60")

+

+        #increased SIP

+        input_pkt = simple_packet(

+                '00 00 00 00 02 00 00 00 00 00 02 01 81 00 00 c8 '

+                '08 00 45 00 00 2a 04 d2 00 00 7f 06 0a fa c8 00 '

+                '00 01 64 00 00 01 0b 0c 13 88 00 01 f7 fa 00 00 '

+                '00 00 50 00 04 00 69 50 00 00 00 00')

+

+        #random SIP

+        output_pkt = simple_packet(

+                '00 00 00 00 01 01 00 00 00 00 01 00 81 00 00 64 '

+                '08 00 45 00 00 2a 04 d2 00 00 7e 06 65 ee c8 00 '

+                '00 0d 0a 00 00 01 0b 0c 07 d0 00 01 f7 fa 00 00 '

+                '00 00 50 00 04 00 ce fc 00 00 00 00')

+

+        #random SIP

+        output_pkt2 = simple_packet(

+                '00 00 05 22 44 66 00 00 05 22 33 55 81 00 00 02 '

+                '08 00 45 00 00 2a 04 d2 00 00 7e 06 65 ef c8 00 '

+                '00 0c 0a 00 00 01 0b 0c 07 d0 00 01 f7 fa 00 00 '

+                '00 00 50 00 04 00 ce fd 00 00 00 00')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt2), output_port2)

+

+

+class dnat_decap_mpls(base_tests.SimpleDataPlane):

+    """

+    [Decap MPLS label and DNAT]

+      Decap MPLS label and DNAT

+

+    Inject  eth 1/3 Tag 12, SA000000112233, DA000000000111, MPLS 0x1234, SIP 200.0.0.1, DIP 100.0.0.1

+    Output  eth 1/1 DA000000000101, SA000000000100, Tag 100, SIP 200.0.0.1, DIP 10.0.0.01

+

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x640001 group=any,port=any,weight=0 output=1

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x23000001 group=any,port=any,weight=0 set_field=eth_src=00:00:00:00:01:00,set_field=eth_dst=00:00:00:00:01:01,set_field=vlan_vid=100,group=0x640001

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=3,vlan_vid=0x100c/0x1fff apply:set_field=ofdpa_vrf:1 goto:20

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=20,cmd=add,prio=201 vlan_vid=12/0xfff,eth_dst=00:00:00:00:01:11,eth_type=0x8847 goto:24

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=24,cmd=add,prio=204 eth_type=0x8847,mpls_label=0x1234,mpls_bos=1,ofdpa_mpls_data_first_nibble=4 apply:mpls_dec,pop_mpls=0x0800,set_field=ofdpa_vrf:1 goto:30

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=28,cmd=add,prio=281 eth_type=0x800,ip_dst=100.0.0.1,ofdpa_vrf=1 write:set_field=ip_dst:10.0.0.1,group=0x23000001 goto:60

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x64000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x23000001 group=any,port=any,weight=0 set_field=eth_src=00:00:00:00:01:00,set_field=eth_dst=00:00:00:00:01:01,set_field=vlan_vid=100,group=0x64000"+str(output_port))

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x100c/0x1fff apply:set_field=ofdpa_vrf:1 goto:20")

+        apply_dpctl_mod(self, config, "flow-mod table=20,cmd=add,prio=201 vlan_vid=12/0xfff,eth_dst=00:00:00:00:01:11,eth_type=0x8847 goto:24")

+        apply_dpctl_mod(self, config, "flow-mod table=24,cmd=add,prio=204 eth_type=0x8847,mpls_label=0x1234,mpls_bos=1,ofdpa_mpls_data_first_nibble=4 apply:mpls_dec,pop_mpls=0x0800,set_field=ofdpa_vrf:1 goto:30")

+        apply_dpctl_mod(self, config, "flow-mod table=28,cmd=add,prio=281 eth_type=0x800,ip_dst=100.0.0.1,ofdpa_vrf=1 write:set_field=ip_dst:10.0.0.1,group=0x23000001 goto:60")

+

+        input_pkt = simple_packet(

+                '00 00 00 00 01 11 00 00 00 11 22 33 81 00 00 0c '

+                '88 47 01 23 41 3f 45 00 00 26 00 00 00 00 3f 00 '

+                '4f d6 c8 00 00 01 64 00 00 01 00 01 02 03 04 05 '

+                '06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 '

+                '16 17 18 19')

+

+        output_pkt = simple_packet(

+                '00 00 00 00 01 01 00 00 00 00 01 00 81 00 00 64 '

+                '08 00 45 00 00 26 00 00 00 00 3e 00 aa d6 c8 00 '

+                '00 01 0a 00 00 01 00 01 02 03 04 05 06 07 08 09 '

+                '0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+

+

+class snat(base_tests.SimpleDataPlane):

+    """

+    [SNAT]

+      SNAT (outbound)

+

+    Inject  eth 1/1 DA000000000100, SA000000000101, Tag 100, SIP 10.0.0.1, DIP 200.0.0.01, Sport 2000, Dport 2828

+    Output  eth 1/3 DA000000000200, SA000000000201, Tag 200, SIP 100.0.0.1, DIP 200.0.0.01, Sport 5000, Dport 2828

+

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=1,vlan_vid=0x1064/0x1fff goto:20

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=20,cmd=add,prio=201 vlan_vid=100/0xfff,eth_dst=00:00:00:00:01:00,eth_type=0x0800 goto:29

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0xC80003 group=any,port=any,weight=0 output=3

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x22000002 group=any,port=any,weight=0 set_field=eth_src=00:00:00:00:02:00,set_field=eth_dst=00:00:00:00:02:01,set_field=vlan_vid=200,group=0xC80003

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=29,cmd=add,prio=291 eth_type=0x800,ip_src=10.0.0.1,ip_proto=6,tcp_src=2000 write:set_field=ip_src:100.0.0.1,set_field=tcp_src:5000 goto:30

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=30,cmd=add,prio=301 eth_type=0x0800,ip_dst=200.0.0.1/255.255.255.0 write:group=0x22000002 goto:60

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1064/0x1fff goto:20")

+        apply_dpctl_mod(self, config, "flow-mod table=20,cmd=add,prio=201 vlan_vid=100/0xfff,eth_dst=00:00:00:00:01:00,eth_type=0x0800 goto:29")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0xC8000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x22000002 group=any,port=any,weight=0 set_field=eth_src=00:00:00:00:02:00,set_field=eth_dst=00:00:00:00:02:01,set_field=vlan_vid=200,group=0xC8000"+str(output_port))

+        apply_dpctl_mod(self, config, "flow-mod table=29,cmd=add,prio=291 eth_type=0x800,ip_src=10.0.0.1,ip_proto=6,tcp_src=2000 write:set_field=ip_src:100.0.0.1,set_field=tcp_src:5000 goto:30")

+        apply_dpctl_mod(self, config, "flow-mod table=30,cmd=add,prio=301 eth_type=0x0800,ip_dst=200.0.0.1/255.255.255.0 write:group=0x22000002 goto:60")

+

+        input_pkt = simple_packet(

+                '00 00 00 00 01 00 00 00 00 00 02 00 81 00 00 64 '

+                '08 00 45 00 00 2e 04 d2 00 00 7f 06 64 f6 0a 00 '

+                '00 01 c8 00 00 01 07 d0 0b 0c 00 01 f7 fa 00 00 '

+                '00 00 50 00 04 00 cf 04 00 00 00 00 00 00 00 00')

+

+        output_pkt = simple_packet(

+                '00 00 00 00 02 01 00 00 00 00 02 00 81 00 00 c8 '

+                '08 00 45 00 00 2e 04 d2 00 00 7e 06 0b f6 64 00 '

+                '00 01 c8 00 00 01 13 88 0b 0c 00 01 f7 fa 00 00 '

+                '00 00 50 00 04 00 69 4c 00 00 00 00 00 00 00 00')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+

+

+class snat_vrf(base_tests.SimpleDataPlane):

+    """

+    [SNAT VRF]

+      SNAT (outbound) with specified VRF

+

+    Inject  eth 1/1 DA000000000100, SA000000000101, Tag 100, SIP 10.0.0.1, DIP 200.0.0.01, Sport 2000, Dport 2828

+    Output  eth 1/3 DA000000000200, SA000000000201, Tag 200, SIP 100.0.0.1, DIP 200.0.0.01, Sport 5000, Dport 2828

+

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=1,vlan_vid=0x1064/0x1fff goto:20 apply:set_field=ofdpa_vrf:3

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=1,vlan_vid=0x10c8/0x1fff goto:20 apply:set_field=ofdpa_vrf:3

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=20,cmd=add,prio=201 vlan_vid=100/0xfff,eth_dst=00:00:00:00:01:00,eth_type=0x0800 goto:29

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0xC80003 group=any,port=any,weight=0 output=3

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x22000002 group=any,port=any,weight=0 set_field=eth_src=00:00:00:00:02:00,set_field=eth_dst=00:00:00:00:02:01,set_field=vlan_vid=200,group=0xC80003

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=29,cmd=add,prio=291 eth_type=0x800,ip_src=10.0.0.1,ip_proto=6,tcp_src=2000,ofdpa_vrf=3 write:set_field=ip_src:100.0.0.1,set_field=tcp_src:5000 goto:30

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=30,cmd=add,prio=301 eth_type=0x0800,ip_dst=200.0.0.1/255.255.255.0,ofdpa_vrf=3 write:group=0x22000002 goto:60

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1064/0x1fff goto:20 apply:set_field=ofdpa_vrf:3")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x10c8/0x1fff goto:20 apply:set_field=ofdpa_vrf:3")

+        apply_dpctl_mod(self, config, "flow-mod table=20,cmd=add,prio=201 vlan_vid=100/0xfff,eth_dst=00:00:00:00:01:00,eth_type=0x0800 goto:29")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0xC8000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x22000002 group=any,port=any,weight=0 set_field=eth_src=00:00:00:00:02:00,set_field=eth_dst=00:00:00:00:02:01,set_field=vlan_vid=200,group=0xC8000"+str(output_port))

+        apply_dpctl_mod(self, config, "flow-mod table=29,cmd=add,prio=291 eth_type=0x800,ip_src=10.0.0.1,ip_proto=6,tcp_src=2000,ofdpa_vrf=3 write:set_field=ip_src:100.0.0.1,set_field=tcp_src:5000 goto:30")

+        apply_dpctl_mod(self, config, "flow-mod table=30,cmd=add,prio=301 eth_type=0x0800,ip_dst=200.0.0.1/255.255.255.0,ofdpa_vrf=3 write:group=0x22000002 goto:60")

+

+        input_pkt = simple_packet(

+                '00 00 00 00 01 00 00 00 00 00 02 00 81 00 00 64 '

+                '08 00 45 00 00 2e 04 d2 00 00 7f 06 64 f6 0a 00 '

+                '00 01 c8 00 00 01 07 d0 0b 0c 00 01 f7 fa 00 00 '

+                '00 00 50 00 04 00 cf 04 00 00 00 00 00 00 00 00')

+

+        output_pkt = simple_packet(

+                '00 00 00 00 02 01 00 00 00 00 02 00 81 00 00 c8 '

+                '08 00 45 00 00 2e 04 d2 00 00 7e 06 0b f6 64 00 '

+                '00 01 c8 00 00 01 13 88 0b 0c 00 01 f7 fa 00 00 '

+                '00 00 50 00 04 00 69 4c 00 00 00 00 00 00 00 00')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+

+"""

+currently this case will fail, due to packet rx src IP problem

+"""

+class snat_ecmp(base_tests.SimpleDataPlane):

+    """

+    [SNAT ECMP]

+      SNAT (outbound) with ECMP

+

+    Inject  eth 1/1 DA000000000100, SA000000000101, Tag 100, SIP 10.0.0.1, DIP 200.0.0.01, Sport 2000, Dport 2828 [increase DIP]

+    Output  eth 1/3 DA000000000200, SA000000000201, Tag 200, SIP 100.0.0.1, DIP 200.0.0.X, Sport 5000, Dport 2828

+    Output  eth 1/5 DA000000000500, SA000000000501, Tag 5, SIP 100.0.0.1, DIP 200.0.0.X, Sport 5000, Dport 2828

+

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=1,vlan_vid=0x1064/0x1fff goto:20

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=20,cmd=add,prio=201 vlan_vid=100/0xfff,eth_dst=00:00:00:00:01:00,eth_type=0x0800 goto:29

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0xC80003 group=any,port=any,weight=0 output=3

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x22000002 group=any,port=any,weight=0 set_field=eth_src=00:00:00:00:02:00,set_field=eth_dst=00:00:00:00:02:01,set_field=vlan_vid=200,group=0xC80003

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x50005 group=any,port=any,weight=0 output=5

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x22000005 group=any,port=any,weight=0 set_field=eth_src=00:00:00:00:05:00,set_field=eth_dst=00:00:00:00:05:01,set_field=vlan_vid=5,group=0x50005

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=sel,group=0x71000001 group=any,port=any,weight=0 group=0x22000002 group=any,port=any,weight=0 group=0x22000005

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=29,cmd=add,prio=291 eth_type=0x800,ip_src=10.0.0.1,ip_proto=6,tcp_src=2000 write:set_field=ip_src:100.0.0.1,set_field=tcp_src:5000 goto:30

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=30,cmd=add,prio=301 eth_type=0x0800,ip_dst=200.0.0.1/255.255.255.0 write:group=0x71000001 goto:60

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+        output_port2 = test_ports[2]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1064/0x1fff goto:20")

+        apply_dpctl_mod(self, config, "flow-mod table=20,cmd=add,prio=201 vlan_vid=100/0xfff,eth_dst=00:00:00:00:01:00,eth_type=0x0800 goto:29")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0xC8000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x22000002 group=any,port=any,weight=0 set_field=eth_src=00:00:00:00:02:00,set_field=eth_dst=00:00:00:00:02:01,set_field=vlan_vid=200,group=0xC8000"+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x5000"+str(output_port2)+" group=any,port=any,weight=0 output="+str(output_port2))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x22000005 group=any,port=any,weight=0 set_field=eth_src=00:00:00:00:05:00,set_field=eth_dst=00:00:00:00:05:01,set_field=vlan_vid=5,group=0x5000"+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=sel,group=0x71000001 group=any,port=any,weight=0 group=0x22000002 group=any,port=any,weight=0 group=0x22000005")

+        apply_dpctl_mod(self, config, "flow-mod table=29,cmd=add,prio=291 eth_type=0x800,ip_src=10.0.0.1,ip_proto=6,tcp_src=2000 write:set_field=ip_src:100.0.0.1,set_field=tcp_src:5000 goto:30")

+        apply_dpctl_mod(self, config, "flow-mod table=30,cmd=add,prio=301 eth_type=0x0800,ip_dst=200.0.0.1/255.255.255.0 write:group=0x71000001 goto:60")

+

+        #increased DIP

+        input_pkt = simple_packet(

+                '00 00 00 00 01 00 00 00 00 00 02 00 81 00 00 64 '

+                '08 00 45 00 00 2e 04 d2 00 00 7f 06 64 f6 0a 00 '

+                '00 01 c8 00 00 01 07 d0 0b 0c 00 01 f7 fa 00 00 '

+                '00 00 50 00 04 00 cf 04 00 00 00 00 00 00 00 00')

+

+        #rnadom DIP

+        output_pkt = simple_packet(

+                '00 00 00 00 02 01 00 00 00 00 02 00 81 00 00 c8 '

+                '08 00 45 00 00 2e 04 d2 00 00 7e 06 0b e8 64 00 '

+                '00 01 c8 00 00 0f 13 88 0b 0c 00 01 f7 fa 00 00 '

+                '00 00 50 00 04 00 69 3e 00 00 00 00 00 00 00 00')

+

+        #rnadom DIP

+        output_pkt2 = simple_packet(

+                '00 00 00 00 05 01 00 00 00 00 05 00 81 00 00 05 '

+                '08 00 45 00 00 2e 04 d2 00 00 7e 06 0b f4 64 00 '

+                '00 01 c8 00 00 03 13 88 0b 0c 00 01 f7 fa 00 00 '

+                '00 00 50 00 04 00 69 4a 00 00 00 00 00 00 00 00')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt2), output_port2)

diff --git a/Fabric/Utilities/acctonUseDpctl/phase1.py b/Fabric/Utilities/acctonUseDpctl/phase1.py
new file mode 100755
index 0000000..95cba29
--- /dev/null
+++ b/Fabric/Utilities/acctonUseDpctl/phase1.py
@@ -0,0 +1,421 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+import logging

+import oftest.base_tests as base_tests

+from oftest import config

+from oftest.testutils import *

+from util import *

+from accton_util import convertIP4toStr as toIpV4Str

+from accton_util import convertMACtoStr as toMacStr

+

+

+class l3ucast_route(base_tests.SimpleDataPlane):

+    """

+    [L3 unicast route]

+      Do unicast route and output to specified port

+

+    Inject  eth 1/3 Tag2, SA000000112233, DA7072cf7cf3a3, SIP 192.168.1.100, DIP 192.168.2.2

+    Output  eth 1/1 Tag3, SA 000004223355, DA 000004224466

+

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=0,cmd=add,prio=1 in_port=0/0xffff0000 goto:10

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=3,vlan_vid=0x1002/0x1fff goto:20

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=20,cmd=add,prio=201 in_port=3,vlan_vid=2/0xfff,eth_dst=70:72:cf:7c:f3:a3,eth_type=0x0800 goto:30

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x30001 group=any,port=any,weight=0 output=1

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20000003 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:55,set_field=eth_dst=00:00:04:22:44:66,set_field=vlan_vid=3,group=0x30001

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=30,cmd=add,prio=301 eth_type=0x0800,ip_dst=192.168.2.2/255.255.255.0 write:group=0x20000003 goto:60

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "flow-mod table=0,cmd=add,prio=1 in_port=0/0xffff0000 goto:10")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1002/0x1fff goto:20")

+        apply_dpctl_mod(self, config, "flow-mod table=20,cmd=add,prio=201 in_port="+str(input_port)+",eth_dst=70:72:cf:7c:f3:a3,eth_type=0x0800 goto:30")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x3000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x20000003 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:55,set_field=eth_dst=00:00:04:22:44:66,set_field=vlan_vid=3,group=0x3000"+str(output_port))

+        apply_dpctl_mod(self, config, "flow-mod table=30,cmd=add,prio=301 eth_type=0x0800,ip_dst=192.168.2.2/255.255.255.0 write:group=0x20000003 goto:60")

+

+        input_pkt = simple_packet(

+                '70 72 cf 7c f3 a3 00 00 00 11 22 33 81 00 00 02 '

+                '08 00 45 00 00 4e 04 d2 00 00 7f 06 b2 7b c0 a8 '

+                '01 0a c0 a8 02 02 00 03 00 06 00 01 f7 fa 00 00 '

+                '00 00 50 00 04 00 2f 5d 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        output_pkt = simple_packet(

+                '00 00 04 22 44 66 00 00 04 22 33 55 81 00 00 03 '

+                '08 00 45 00 00 4e 04 d2 00 00 7e 06 b3 7b c0 a8 '

+                '01 0a c0 a8 02 02 00 03 00 06 00 01 f7 fa 00 00 '

+                '00 00 50 00 04 00 2f 5d 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+

+

+class l3ucast_route6(base_tests.SimpleDataPlane):

+    """

+    [L3 IPv6 unicast route]

+      Do unicast route and output to specified port

+

+    Inject  eth 1/3 Tag2, SA000000112233, DA7072cf7cf3a3, SIP 2014::2, DIP 2014::1

+    Output  eth 1/1 Tag2, SA 000004223355, DA 000004224466

+

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=0,cmd=add,prio=1 in_port=0/0xffff0000 goto:10

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=3,vlan_vid=0x1002/0x1fff goto:20

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=20,cmd=add,prio=201 in_port=3,vlan_vid=2/0xfff,eth_dst=70:72:cf:7c:f3:a3,eth_type=0x86dd goto:30

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20001 group=any,port=any,weight=0 output=1

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:55,set_field=eth_dst=00:00:04:22:44:66,set_field=vlan_vid=2,group=0x20001

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=30,cmd=add,prio=301 eth_type=0x86dd,ipv6_dst=2014::1/64 write:group=0x20000001 goto:60

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "flow-mod table=0,cmd=add,prio=1 in_port=0/0xffff0000 goto:10")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1002/0x1fff goto:20")

+        apply_dpctl_mod(self, config, "flow-mod table=20,cmd=add,prio=201 in_port="+str(input_port)+",eth_dst=70:72:cf:7c:f3:a3,eth_type=0x86dd goto:30")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x20000001 group=any,port=any,weight=0 set_field=eth_src=00:00:04:22:33:55,set_field=eth_dst=00:00:04:22:44:66,set_field=vlan_vid=2,group=0x2000"+str(output_port))

+        apply_dpctl_mod(self, config, "flow-mod table=30,cmd=add,prio=301 eth_type=0x86dd,ipv6_dst=2014::1/64 write:group=0x20000001 goto:60")

+

+        input_pkt = simple_packet(

+                '70 72 cf 7c f3 a3 00 00 00 11 22 33 81 00 00 02 '

+                '86 dd 60 00 00 00 00 08 11 7f 20 14 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 02 20 14 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 01 00 0d 00 07 00 08 '

+                'bf 9f 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        output_pkt = simple_packet(

+                '00 00 04 22 44 66 00 00 04 22 33 55 81 00 00 02 '

+                '86 dd 60 00 00 00 00 08 11 7e 20 14 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 02 20 14 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 01 00 0d 00 07 00 08 '

+                'bf 9f 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+

+

+class l3mcast_route(base_tests.SimpleDataPlane):

+    """

+    [L3 multicast route]

+      Do multicast route and output to specified ports

+

+    Inject  eth 1/3 Tag2, SA000000112233, DA01005E404477, SIP 192.168.1.100, DIP 224.0.2.2

+    Output  eth 1/1 original

+

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=0,cmd=add,prio=1 in_port=0/0xffff0000 goto:10

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=3,vlan_vid=0x1002/0x1fff goto:20

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=20,cmd=add,prio=201 eth_dst=01:00:5e:40:44:77/ff:ff:ff:80:00:00,eth_type=0x0800 goto:40

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20001 group=any,port=any,weight=0 output=1

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=all,group=0x60020001 group=any,port=any,weight=0 group=0x20001

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=40,cmd=add,prio=401 eth_type=0x0800,ip_src=192.168.2.2,ip_dst=224.0.2.2,vlan_vid=2 write:group=0x60020001 goto:60

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "flow-mod table=0,cmd=add,prio=1 in_port=0/0xffff0000 goto:10")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1002/0x1fff goto:20")

+        apply_dpctl_mod(self, config, "flow-mod table=20,cmd=add,prio=201 eth_dst=01:00:5e:40:44:77/ff:ff:ff:80:00:00,eth_type=0x0800 goto:40")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=all,group=0x60020001 group=any,port=any,weight=0 group=0x2000"+str(output_port))

+        apply_dpctl_mod(self, config, "flow-mod table=40,cmd=add,prio=401 eth_type=0x0800,ip_src=192.168.2.2,ip_dst=224.0.2.2,vlan_vid=2 write:group=0x60020001 goto:60")

+

+        input_pkt = simple_packet(

+                '01 00 5e 40 44 77 00 00 00 11 22 33 81 00 00 02 '

+                '08 00 45 00 00 4e 04 d2 00 00 7f 84 91 ad c0 a8 '

+                '02 02 e0 00 02 02 00 17 00 08 00 01 f7 fa 00 00 '

+                '00 00 50 00 04 00 0e 79 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        output_pkt = simple_packet(

+                '01 00 5e 40 44 77 00 00 00 11 22 33 81 00 00 02 '

+                '08 00 45 00 00 4e 04 d2 00 00 7f 84 91 ad c0 a8 '

+                '02 02 e0 00 02 02 00 17 00 08 00 01 f7 fa 00 00 '

+                '00 00 50 00 04 00 0e 79 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+

+

+class l3mcast_route6(base_tests.SimpleDataPlane):

+    """

+    [L3 IPv6 multicast route]

+      Do multicast route and output to specified ports

+

+    Inject  eth 1/5 Tag2, SA000000112233, DA333300224477, SIP 2014::2, DIP ff01::2

+    Output  eth 1/1 Tag2, original

+    Output  eth 1/3 Tag3, original

+

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=0,cmd=add,prio=1 in_port=0/0xffff0000 goto:10

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=5,vlan_vid=0x1002/0x1fff goto:20

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=20,cmd=add,prio=201 eth_dst=33:33:00:22:44:77/ff:ff:00:00:00:00,eth_type=0x86dd goto:40

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20001 group=any,port=any,weight=0 output=1

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x30003 group=any,port=any,weight=0 output=3

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x50000003 group=any,port=any,weight=0 set_field=eth_src=00:00:05:22:33:99,set_field=vlan_vid=3,group=0x30003

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=all,group=0x60020001 group=any,port=any,weight=0 group=0x20001 group=any,port=any,weight=0 group=0x50000003

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=40,cmd=add,prio=501 eth_type=0x86dd,ipv6_dst=ff01::2,vlan_vid=2 write:group=0x60020001 goto:60

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+        output_port2 = test_ports[2]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "flow-mod table=0,cmd=add,prio=1 in_port=0/0xffff0000 goto:10")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1002/0x1fff goto:20")

+        apply_dpctl_mod(self, config, "flow-mod table=20,cmd=add,prio=201 eth_dst=33:33:00:22:44:77/ff:ff:00:00:00:00,eth_type=0x86dd goto:40")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x3000"+str(output_port2)+" group=any,port=any,weight=0 output="+str(output_port2))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x50000003 group=any,port=any,weight=0 set_field=eth_src=00:00:05:22:33:99,set_field=vlan_vid=3,group=0x3000"+str(output_port2))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=all,group=0x60020001 group=any,port=any,weight=0 group=0x2000"+str(output_port)+" group=any,port=any,weight=0 group=0x50000003")

+        apply_dpctl_mod(self, config, "flow-mod table=40,cmd=add,prio=401 eth_type=0x86dd,ipv6_dst=ff01::2,vlan_vid=2 write:group=0x60020001 goto:60")

+

+        input_pkt = simple_packet(

+                '33 33 00 22 44 77 00 00 00 11 22 33 81 00 00 02 '

+                '86 dd 60 00 00 00 00 26 3b 7f 20 14 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 01 ff 01 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        output_pkt = simple_packet(

+                '33 33 00 22 44 77 00 00 00 11 22 33 81 00 00 02 '

+                '86 dd 60 00 00 00 00 26 3b 7f 20 14 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 01 ff 01 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        output_pkt2 = simple_packet(

+                '33 33 00 22 44 77 00 00 05 22 33 99 81 00 00 03 '

+                '86 dd 60 00 00 00 00 26 3b 7e 20 14 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 01 ff 01 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+        verify_packet(self, str(output_pkt2), output_port2)

+

+

+class bridge_ucast(base_tests.SimpleDataPlane):

+    """

+    [Bridge unicast]

+      Do unicast bridge

+

+    Inject  eth 1/1 Tag2, SA000000112233, DA000000224477, SIP 192.168.2.1, DIP 192.168.2.2

+    Output  eth 1/3 untag

+

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=0,cmd=add,prio=1 in_port=0/0xffff0000 goto:10

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=1,vlan_vid=0x1002/0x1fff goto:20

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20003 group=any,port=any,weight=0 pop_vlan,output=3

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=50,cmd=add,prio=501 vlan_vid=2,eth_dst=00:00:00:22:44:77 write:group=0x20003 goto:60

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "flow-mod table=0,cmd=add,prio=1 in_port=0/0xffff0000 goto:10")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1002/0x1fff goto:20")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(output_port)+" group=any,port=any,weight=0 pop_vlan,output="+str(output_port))

+        apply_dpctl_mod(self, config, "flow-mod table=50,cmd=add,prio=501 vlan_vid=2,eth_dst=00:00:00:22:44:77 write:group=0x2000"+str(output_port)+" goto:60")

+

+        input_pkt = simple_packet(

+                '00 00 00 22 44 77 00 00 00 11 22 33 81 00 00 02 '

+                '08 00 45 00 00 4e 04 d2 00 00 7f 00 b1 8a c0 a8 '

+                '02 01 c0 a8 02 02 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        output_pkt = simple_packet(

+                '00 00 00 22 44 77 00 00 00 11 22 33 08 00 45 00 '

+                '00 4e 04 d2 00 00 7f 00 b1 8a c0 a8 02 01 c0 a8 '

+                '02 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+

+

+class bridge_mcast(base_tests.SimpleDataPlane):

+    """

+    [Bridge multicast]

+      Do multicast bridge

+

+    Inject  eth 1/5 Tag2, SA000000112233, DA110000224477, SIP 192.168.2.1, DIP 192.168.2.2

+    Output  eth 1/1 Tag2, SA000000112233, DA110000224477, SIP 192.168.2.1, DIP 192.168.2.2

+    Output  eth 1/3 untag

+

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=0,cmd=add,prio=1 in_port=0/0xffff0000 goto:10

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=5,vlan_vid=0x1002/0x1fff goto:20

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20001 group=any,port=any,weight=0 output=1

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20003 group=any,port=any,weight=0 pop_vlan,output=3

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=all,group=0x30020001 group=any,port=any,weight=0 group=0x20001 group=any,port=any,weight=0 group=0x20003

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=50,cmd=add,prio=601 vlan_vid=2,eth_dst=11:00:00:22:44:77 write:group=0x30020001 goto:60

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+        output_port2 = test_ports[2]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "flow-mod table=0,cmd=add,prio=1 in_port=0/0xffff0000 goto:10")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1002/0x1fff goto:20")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(output_port2)+" group=any,port=any,weight=0 pop_vlan,output="+str(output_port2))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=all,group=0x30020001 group=any,port=any,weight=0 group=0x2000"+str(output_port)+" group=any,port=any,weight=0 group=0x2000"+str(output_port2))

+        apply_dpctl_mod(self, config, "flow-mod table=50,cmd=add,prio=501 vlan_vid=2,eth_dst=11:00:00:22:44:77 write:group=0x30020001 goto:60")

+

+        input_pkt = simple_packet(

+                '11 00 00 22 44 77 00 00 00 11 22 33 81 00 00 02 '

+                '08 00 45 00 00 4e 04 d2 00 00 7f 00 b1 8a c0 a8 '

+                '02 01 c0 a8 02 02 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        output_pkt = simple_packet(

+                '11 00 00 22 44 77 00 00 00 11 22 33 81 00 00 02 '

+                '08 00 45 00 00 4e 04 d2 00 00 7f 00 b1 8a c0 a8 '

+                '02 01 c0 a8 02 02 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        output_pkt2 = simple_packet(

+                '11 00 00 22 44 77 00 00 00 11 22 33 08 00 45 00 '

+                '00 4e 04 d2 00 00 7f 00 b1 8a c0 a8 02 01 c0 a8 '

+                '02 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+        verify_packet(self, str(output_pkt2), output_port2)

+

+

+class bridge_dlf(base_tests.SimpleDataPlane):

+    """

+    [Bridge DLF]

+      Do DLF bridge

+

+    Inject  eth 1/5 Tag2, SA000000112233, DA110000224466, SIP 192.168.2.1, DIP 192.168.2.2

+    Output  eth 1/1 Tag2, SA000000112233, DA110000224477, SIP 192.168.2.1, DIP 192.168.2.2

+    Output  eth 1/3 untag

+

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=0,cmd=add,prio=1 in_port=0/0xffff0000 goto:10

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=5,vlan_vid=0x1002/0x1fff goto:20

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20001 group=any,port=any,weight=0 output=1

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20003 group=any,port=any,weight=0 pop_vlan,output=3

+    ./dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=all,group=0x40020001 group=any,port=any,weight=0 group=0x20001 group=any,port=any,weight=0 group=0x20003

+    ./dpctl tcp:192.168.1.1:6633 flow-mod table=50,cmd=add,prio=601 vlan_vid=2 write:group=0x40020001 goto:60

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+        output_port2 = test_ports[2]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "flow-mod table=0,cmd=add,prio=1 in_port=0/0xffff0000 goto:10")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1002/0x1fff goto:20")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(output_port2)+" group=any,port=any,weight=0 pop_vlan,output="+str(output_port2))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=all,group=0x40020001 group=any,port=any,weight=0 group=0x2000"+str(output_port)+" group=any,port=any,weight=0 group=0x2000"+str(output_port2))

+        apply_dpctl_mod(self, config, "flow-mod table=50,cmd=add,prio=601 vlan_vid=2 write:group=0x40020001 goto:60")

+

+        input_pkt = simple_packet(

+                '00 00 00 22 44 66 00 00 00 11 22 33 81 00 00 02 '

+                '08 00 45 00 00 4e 04 d2 00 00 7f 00 b1 8a c0 a8 '

+                '02 01 c0 a8 02 02 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        output_pkt = simple_packet(

+                '00 00 00 22 44 66 00 00 00 11 22 33 81 00 00 02 '

+                '08 00 45 00 00 4e 04 d2 00 00 7f 00 b1 8a c0 a8 '

+                '02 01 c0 a8 02 02 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        output_pkt2 = simple_packet(

+                '00 00 00 22 44 66 00 00 00 11 22 33 08 00 45 00 '

+                '00 4e 04 d2 00 00 7f 00 b1 8a c0 a8 02 01 c0 a8 '

+                '02 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+        verify_packet(self, str(output_pkt2), output_port2)

+

diff --git a/Fabric/Utilities/acctonUseDpctl/pim_bidr.py b/Fabric/Utilities/acctonUseDpctl/pim_bidr.py
new file mode 100755
index 0000000..7d06450
--- /dev/null
+++ b/Fabric/Utilities/acctonUseDpctl/pim_bidr.py
@@ -0,0 +1,183 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+import logging

+import oftest.base_tests as base_tests

+from oftest import config

+from oftest.testutils import *

+from util import *

+from accton_util import convertIP4toStr as toIpV4Str

+from accton_util import convertMACtoStr as toMacStr

+

+

+class test_v4(base_tests.SimpleDataPlane):

+    """

+    [PIM BIDR IPv4]

+      PIM BIDR IPv4

+

+    Inject  eth 1/3 tag 3, SA unknown, DA 01005E010101, SIP 192.168.2.1, DIP 224.0.0.1

+    Output  eth 1/1 tag 2, SA 000001223355, DA 01005e010101, SIP 192.168.2.1, DIP 224.0.0.1

+

+    Inject  eth 1/1 tag 2, SA unknown, DA 01005E010101, SIP 192.168.2.1, DIP 224.0.0.1

+    Output  eth 1/3 tag 3, SA 000002223355, DA 01005e010101, SIP 192.168.2.1, DIP 224.0.0.1

+

+    ./dpctl tcp:0.0.0.0:6633 flow-mod table=10,cmd=add,prio=101 in_port=1,vlan_vid=0x1002/0x00001fff goto:20

+    ./dpctl tcp:0.0.0.0:6633 flow-mod table=10,cmd=add,prio=101 in_port=3,vlan_vid=0x1003/0x00001fff goto:20

+    ./dpctl tcp:0.0.0.0:6633 flow-mod table=20,cmd=add,prio=201 eth_dst=01:00:5e:01:01:01/ff:ff:ff:80:00:00,eth_type=0x0800 goto:40

+    ./dpctl tcp:0.0.0.0:6633 group-mod cmd=add,type=ind,group=0x20001 group=any,port=any,weight=0 output=1

+    ./dpctl tcp:0.0.0.0:6633 group-mod cmd=add,type=ind,group=0x30003 group=any,port=any,weight=0 output=3

+    ./dpctl tcp:0.0.0.0:6633 group-mod cmd=add,type=ind,group=0x58000001 group=any,port=any,weight=0 set_field=eth_src=00:00:01:22:33:55,set_field=vlan_vid=2,group=0x20001

+    ./dpctl tcp:0.0.0.0:6633 group-mod cmd=add,type=ind,group=0x58000002 group=any,port=any,weight=0 set_field=eth_src=00:00:02:22:33:55,set_field=vlan_vid=3,group=0x30003

+    ./dpctl tcp:0.0.0.0:6633 group-mod cmd=add,type=all,group=0x60058001 group=any,port=any,weight=0 group=0x58000001 group=any,port=any,weight=0 group=0x58000002

+    ./dpctl tcp:0.0.0.0:6633 flow-mod table=40,cmd=add,prio=401 eth_type=0x800,ip_dst=224.0.0.1 write:group=0x60058001 goto:60

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(output_port)+",vlan_vid=0x1002/0x00001fff goto:20")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1003/0x00001fff goto:20")

+        apply_dpctl_mod(self, config, "flow-mod table=20,cmd=add,prio=201 eth_dst=01:00:5e:01:01:01/ff:ff:ff:80:00:00,eth_type=0x0800 goto:40")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x3000"+str(input_port)+" group=any,port=any,weight=0 output="+str(input_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x58000001 group=any,port=any,weight=0 set_field=eth_src=00:00:01:22:33:55,set_field=vlan_vid=2,group=0x2000"+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x58000002 group=any,port=any,weight=0 set_field=eth_src=00:00:02:22:33:55,set_field=vlan_vid=3,group=0x3000"+str(input_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=all,group=0x60058001 group=any,port=any,weight=0 group=0x58000001 group=any,port=any,weight=0 group=0x58000002")

+        apply_dpctl_mod(self, config, "flow-mod table=40,cmd=add,prio=401 eth_type=0x800,ip_dst=224.0.0.1 write:group=0x60058001 goto:60")

+

+        input_pkt = simple_packet(

+                '01 00 5e 01 01 01 00 00 00 00 00 aa 81 00 00 03 '

+                '08 00 45 00 00 4e 04 d2 00 00 7f 00 94 33 c0 a8 '

+                '02 01 e0 00 00 01 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        output_pkt = simple_packet(

+                '01 00 5e 01 01 01 00 00 01 22 33 55 81 00 00 02 '

+                '08 00 45 00 00 4e 04 d2 00 00 7e 00 95 33 c0 a8 '

+                '02 01 e0 00 00 01 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+

+        input_pkt = simple_packet(

+                '01 00 5e 01 01 01 00 00 00 00 00 aa 81 00 00 02 '

+                '08 00 45 00 00 4e 04 d2 00 00 7f 00 94 33 c0 a8 '

+                '02 01 e0 00 00 01 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        output_pkt = simple_packet(

+                '01 00 5e 01 01 01 00 00 02 22 33 55 81 00 00 03 '

+                '08 00 45 00 00 4e 04 d2 00 00 7e 00 95 33 c0 a8 '

+                '02 01 e0 00 00 01 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        self.dataplane.send(output_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), input_port)

+

+

+class test_v6(base_tests.SimpleDataPlane):

+    """

+    [PIM BIDR IPv4]

+      PIM BIDR IPv4

+

+    Inject  eth 1/3 tag 3, SA unknown, DA 333300224477, SIP 2015::1, DIP ff01::2, UDP proto

+    Output  eth 1/1 tag 2, SA 000001223355, DA 333300224477, SIP 2015::1, DIP ff01::2

+

+    Inject  eth 1/1 tag 2, SA unknown, DA 333300224477, SIP 2015::1, DIP ff01::2, UDP proto

+    Output  eth 1/3 tag 3, SA 000002223355, DA 333300224477, SIP 2015::1, DIP ff01::2

+

+    ./dpctl tcp:0.0.0.0:6633 flow-mod table=10,cmd=add,prio=101 in_port=1,vlan_vid=0x1002/0x1fff goto:20

+    ./dpctl tcp:0.0.0.0:6633 flow-mod table=10,cmd=add,prio=101 in_port=3,vlan_vid=0x1003/0x1fff goto:20

+    ./dpctl tcp:0.0.0.0:6633 flow-mod table=20,cmd=add,prio=201 eth_dst=33:33:00:22:44:77/ff:ff:00:00:00:00,eth_type=0x86dd goto:40

+    ./dpctl tcp:0.0.0.0:6633 group-mod cmd=add,type=ind,group=0x20001 group=any,port=any,weight=0 output=1

+    ./dpctl tcp:0.0.0.0:6633 group-mod cmd=add,type=ind,group=0x30003 group=any,port=any,weight=0 output=3

+    ./dpctl tcp:0.0.0.0:6633 group-mod cmd=add,type=ind,group=0x58000001 group=any,port=any,weight=0 set_field=eth_src=00:00:01:22:33:55,set_field=vlan_vid=2,group=0x20001

+    ./dpctl tcp:0.0.0.0:6633 group-mod cmd=add,type=ind,group=0x58000002 group=any,port=any,weight=0 set_field=eth_src=00:00:02:22:33:55,set_field=vlan_vid=3,group=0x30003

+    ./dpctl tcp:0.0.0.0:6633 group-mod cmd=add,type=all,group=0x60058001 group=any,port=any,weight=0 group=0x58000001 group=any,port=any,weight=0 group=0x58000002

+    ./dpctl tcp:0.0.0.0:6633 flow-mod table=40,cmd=add,prio=401 eth_type=0x86dd,ipv6_dst=ff01::2 write:group=0x60058001 goto:60

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(output_port)+",vlan_vid=0x1002/0x00001fff goto:20")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1003/0x00001fff goto:20")

+        apply_dpctl_mod(self, config, "flow-mod table=20,cmd=add,prio=201 eth_dst=33:33:00:22:44:77/ff:ff:00:00:00:00,eth_type=0x86dd goto:40")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x3000"+str(input_port)+" group=any,port=any,weight=0 output="+str(input_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x58000001 group=any,port=any,weight=0 set_field=eth_src=00:00:01:22:33:55,set_field=vlan_vid=2,group=0x2000"+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x58000002 group=any,port=any,weight=0 set_field=eth_src=00:00:02:22:33:55,set_field=vlan_vid=3,group=0x3000"+str(input_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=all,group=0x60058001 group=any,port=any,weight=0 group=0x58000001 group=any,port=any,weight=0 group=0x58000002")

+        apply_dpctl_mod(self, config, "flow-mod table=40,cmd=add,prio=401 eth_type=0x86dd,ipv6_dst=ff01::2 write:group=0x60058001 goto:60")

+

+        input_pkt = simple_packet(

+                '33 33 00 22 44 77 00 00 00 00 00 aa 81 00 00 03 '

+                '86 dd 60 00 00 00 00 26 11 7f 20 15 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 01 ff 01 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 02 00 3f 00 41 00 26 '

+                '71 8f 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d '

+                '0e 0f 10 11 12 13 14 15 00 00 00 00 00 00 00 00')

+

+        output_pkt = simple_packet(

+                '33 33 00 22 44 77 00 00 01 22 33 55 81 00 00 02 '

+                '86 dd 60 00 00 00 00 26 11 7e 20 15 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 01 ff 01 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 02 00 3f 00 41 00 26 '

+                '71 8f 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d '

+                '0e 0f 10 11 12 13 14 15 00 00 00 00 00 00 00 00')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+

+        input_pkt = simple_packet(

+                '33 33 00 22 44 77 00 00 00 00 00 aa 81 00 00 02 '

+                '86 dd 60 00 00 00 00 26 11 7f 20 15 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 01 ff 01 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 02 00 3f 00 41 00 26 '

+                '71 8f 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d '

+                '0e 0f 10 11 12 13 14 15 00 00 00 00 00 00 00 00')

+

+        output_pkt = simple_packet(

+                '33 33 00 22 44 77 00 00 02 22 33 55 81 00 00 03 '

+                '86 dd 60 00 00 00 00 26 11 7e 20 15 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 01 ff 01 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 02 00 3f 00 41 00 26 '

+                '71 8f 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d '

+                '0e 0f 10 11 12 13 14 15 00 00 00 00 00 00 00 00')

+

+        self.dataplane.send(output_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), input_port)

diff --git a/Fabric/Utilities/acctonUseDpctl/stats.py b/Fabric/Utilities/acctonUseDpctl/stats.py
new file mode 100755
index 0000000..287d80b
--- /dev/null
+++ b/Fabric/Utilities/acctonUseDpctl/stats.py
@@ -0,0 +1,86 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+import logging

+import oftest.base_tests as base_tests

+from oftest import config

+from oftest.testutils import *

+from util import *

+

+

+class table_stats(base_tests.SimpleDataPlane):

+    def runTest(self):

+        json_result = apply_dpctl_get_cmd(self, config, "stats-table")

+        #pprint(json_result)

+        result=json_result["RECEIVED"][1]

+        self.assertNotEqual(result["stats"], {}, "Table stats reply nothing")

+

+class port_stats(base_tests.SimpleDataPlane):

+    def runTest(self):

+        json_result = apply_dpctl_get_cmd(self, config, "stats-port")

+        #pprint(json_result)

+        result=json_result["RECEIVED"][1]

+        self.assertNotEqual(result["stats"], {}, "Ports stats reply nothing")

+

+class queue_stats(base_tests.SimpleDataPlane):

+    def runTest(self):

+        json_result = apply_dpctl_get_cmd(self, config, "stats-queue")

+        #pprint(json_result)

+        result=json_result["RECEIVED"][1]

+        self.assertNotEqual(result["stats"], {}, "Queue stats reply nothing")

+

+class flow_stats(base_tests.SimpleDataPlane):

+    def runTest(self):

+        json_result = apply_dpctl_get_cmd(self, config, "stats-flow")

+        #pprint(json_result)

+        result=json_result["RECEIVED"][1]

+        self.assertNotEqual(result["stats"], {}, "Flow stats reply nothing")

+

+class aggr_stats(base_tests.SimpleDataPlane):

+    def runTest(self):

+        json_result = apply_dpctl_get_cmd(self, config, "stats-aggr")

+        #pprint(json_result)

+        result=json_result["RECEIVED"][1]

+        self.assertNotEqual(result["flow_cnt"], 0, "No flow exist")

+

+class group_stats(base_tests.SimpleDataPlane):

+    def runTest(self):

+        json_result = apply_dpctl_get_cmd(self, config, "stats-group")

+        #pprint(json_result)

+        result=json_result["RECEIVED"][1]

+        self.assertNotEqual(result["stats"], {}, "Group stats reply nothing")

+

+class group_desc_stats(base_tests.SimpleDataPlane):

+    def runTest(self):

+        json_result = apply_dpctl_get_cmd(self, config, "stats-group-desc")

+        #pprint(json_result)

+        result=json_result["RECEIVED"][1]

+        self.assertNotEqual(result["stats"], {}, "Group desc stats reply nothing")

+

+class meter_stats(base_tests.SimpleDataPlane):

+    def runTest(self):

+        json_result = apply_dpctl_get_cmd(self, config, "stats-meter")

+        #pprint(json_result)

+        result=json_result["RECEIVED"][1]

+        self.assertNotEqual(result["stats"], {}, "Meter stats reply nothing")

+

+class meter_config(base_tests.SimpleDataPlane):

+    def runTest(self):

+        json_result = apply_dpctl_get_cmd(self, config, "meter-config")

+        #pprint(json_result)

+        result=json_result["RECEIVED"][1]

+        self.assertNotEqual(result["stats"], {}, "Meter config reply nothing")

+

diff --git a/Fabric/Utilities/acctonUseDpctl/util.py b/Fabric/Utilities/acctonUseDpctl/util.py
new file mode 100755
index 0000000..3942f84
--- /dev/null
+++ b/Fabric/Utilities/acctonUseDpctl/util.py
@@ -0,0 +1,61 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+import subprocess

+import json

+import os

+from pprint import pprint

+import time

+

+test_tmp_file=os.getcwd()+os.sep+"dpctloutputtmp.tmp"

+

+

+def apply_dpctl(test, config, cmd):

+    switch_ip = config["switch_ip"]

+    if len(switch_ip) == 0:

+        assert(0)

+

+    #apply dpctl command     

+    #subprocess.call(os.getcwd()+"/dpctl tcp:"+switch_ip+":6633 "+cmd+" > "+test_tmp_file, shell=True)

+    subprocess.call("dpctl tcp:"+switch_ip+":6633 "+cmd+" > "+test_tmp_file, shell=True)

+    time.sleep(0.2)

+    

+def apply_dpctl_get_cmd(test, config, cmd):

+

+    #create the tmp file

+    if not os.path.isfile(test_tmp_file):

+        open(test_tmp_file, "w").close()

+        subprocess.call(["sudo", "chmod", "a+w", test_tmp_file])

+

+    apply_dpctl(test, config, cmd)

+

+    #parse result

+    with open(test_tmp_file) as tmp_file:

+        try:

+            json_result=json.loads(tmp_file.read(), encoding='utf-8')

+        except ValueError:

+            subprocess.call("cat "+ test_tmp_file, shell=True)

+            """

+            https://docs.python.org/2/library/unittest.html#

+            """            

+            test.assertTrue(False, "NO json format, dpctl may fail")

+    

+    return json_result            

+    

+def apply_dpctl_mod(test, config, cmd):    

+    apply_dpctl(test, config, cmd)

+    

+    
\ No newline at end of file
diff --git a/Fabric/Utilities/acctonUseDpctl/vlan_translate.py b/Fabric/Utilities/acctonUseDpctl/vlan_translate.py
new file mode 100755
index 0000000..653bbad
--- /dev/null
+++ b/Fabric/Utilities/acctonUseDpctl/vlan_translate.py
@@ -0,0 +1,224 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+import logging

+import oftest.base_tests as base_tests

+from oftest import config

+from oftest.testutils import *

+from util import *

+from accton_util import convertIP4toStr as toIpV4Str

+from accton_util import convertMACtoStr as toMacStr

+

+

+class single_tag_to_double_tag(base_tests.SimpleDataPlane):

+    """																					 

+	[Single tag to double tag]																				

+		Add a specified outer tag to incoming tagged packet																			

+																					

+	Inject	eth 1/3	Tag 3, SA000000112233, DA000000113355, V4																		

+	Output	eth 1/1	Outter Tag 5, inner Tag 3, others not change																		

+																					

+	dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=3,vlan_vid=0x1003/0x1fff apply:push_vlan=0x8100,set_field=vlan_vid=5 goto:20																				

+	dpctl tcp:192.168.1.1:6633 flow-mod table=20,cmd=add,prio=201 in_port=3,vlan_vid=3/0xfff,eth_dst=00:00:00:11:33:55,eth_type=0x0800 goto:30																				

+	dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x50001 group=any,port=any,weight=0 output=1																				

+	dpctl tcp:192.168.1.1:6633 flow-mod table=60,cmd=add,prio=601 eth_type=0x0800,in_port=3 write:group=0x50001																				

+	dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x30003 group=any,port=any,weight=0 pop_vlan,output=3																				

+	dpctl tcp:192.168.1.1:6633 flow-mod table=50,cmd=add,prio=501 vlan_vid=3,eth_dst=00:00:00:11:22:33 write:group=0x30003 goto:60																				

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)    

+		

+        test_ports = sorted(config["port_map"].keys())	

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1003/0x1fff apply:push_vlan=0x8100,set_field=vlan_vid=5 goto:20")

+        apply_dpctl_mod(self, config, "flow-mod table=20,cmd=add,prio=201 in_port="+str(input_port)+",vlan_vid=3/0xfff,eth_dst=00:00:00:11:33:55,eth_type=0x0800 goto:30")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x5000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "flow-mod table=60,cmd=add,prio=601 eth_type=0x0800,in_port="+str(input_port)+" write:group=0x5000"+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x3000"+str(input_port)+" group=any,port=any,weight=0 pop_vlan,output="+str(input_port))

+        apply_dpctl_mod(self, config, " flow-mod table=50,cmd=add,prio=501 vlan_vid=3,eth_dst=00:00:00:11:22:33 write:group=0x3000"+str(input_port)+" goto:60")

+

+        input_pkt = simple_packet(

+                '00 00 00 11 33 55 00 00 00 11 22 33 81 00 00 03 '

+                '08 00 45 00 00 2e 04 d2 00 00 7f 00 b2 47 c0 a8 '

+                '01 64 c0 a8 02 02 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        output_pkt = simple_packet(

+                '00 00 00 11 33 55 00 00 00 11 22 33 81 00 00 05 '

+                '81 00 00 03 08 00 45 00 00 2e 04 d2 00 00 7f 00 '

+                'b2 47 c0 a8 01 64 c0 a8 02 02 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00')

+        

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+        

+        

+        

+

+class double_tag_to_single_tag(base_tests.SimpleDataPlane):

+    """																					 

+	[Double tag to single tag]																				

+		Pop outter tag of incoming double tagged packet																			

+																					

+	Inject	eth 1/3	Outer 0x8100 + 6, Inner 0x8100 +3, SA000000112233, DA000000113355, V4																		

+	Output	eth 1/1	Tag 3, others not change																		

+																					

+	dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=3,vlan_vid=0x1006/0x1fff apply:pop_vlan,set_field=ofdpa_ovid:6 goto:11																				

+	dpctl tcp:192.168.1.1:6633 flow-mod table=11,cmd=add,prio=101 in_port=3,vlan_vid=0x1003/0x1fff,ofdpa_ovid=0x1006 goto:20																				

+	dpctl tcp:192.168.1.1:6633 flow-mod table=20,cmd=add,prio=201 in_port=3,vlan_vid=6/0xfff,eth_dst=00:00:00:11:33:55,eth_type=0x0800 goto:30																				

+	dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x30001 group=any,port=any,weight=0 output=1																				

+	dpctl tcp:192.168.1.1:6633 flow-mod table=60,cmd=add,prio=601 eth_type=0x0800,in_port=3 write:group=0x30001																				

+	dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x60003 group=any,port=any,weight=0 output=3																				

+	dpctl tcp:192.168.1.1:6633 flow-mod table=50,cmd=add,prio=501 vlan_vid=6,eth_dst=00:00:00:11:22:33 write:group=0x60003 goto:60																				

+																				

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)    

+		

+        test_ports = sorted(config["port_map"].keys())	

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1006/0x1fff apply:pop_vlan,set_field=ofdpa_ovid:6 goto:11")

+        apply_dpctl_mod(self, config, "flow-mod table=11,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1003/0x1fff,ofdpa_ovid=0x1006 goto:20")

+        apply_dpctl_mod(self, config, "flow-mod table=20,cmd=add,prio=201 in_port="+str(input_port)+",vlan_vid=6/0xfff,eth_dst=00:00:00:11:33:55,eth_type=0x0800 goto:30")        

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x3000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "flow-mod table=60,cmd=add,prio=601 eth_type=0x0800,in_port="+str(input_port)+" write:group=0x3000"+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x6000"+str(input_port)+" group=any,port=any,weight=0 output="+str(input_port))

+        apply_dpctl_mod(self, config, "flow-mod table=50,cmd=add,prio=501 vlan_vid=6,eth_dst=00:00:00:11:22:33 write:group=0x6000"+str(input_port)+" goto:60")

+

+        input_pkt = simple_packet(

+                '00 00 00 11 33 55 00 00 00 11 22 33 81 00 00 06 '

+                '81 00 00 03 08 00 45 00 00 2a 04 d2 00 00 7f 00 '

+                'b2 4b c0 a8 01 64 c0 a8 02 02 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        output_pkt = simple_packet(

+                '00 00 00 11 33 55 00 00 00 11 22 33 81 00 00 03 '

+                '08 00 45 00 00 2a 04 d2 00 00 7f 00 b2 4b c0 a8 '

+                '01 64 c0 a8 02 02 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00')

+        

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)

+                

+        

+

+

+class double2single_vlan_translate(base_tests.SimpleDataPlane):

+    """																					 

+	[Double tag to single tag and modify inner tag]																				

+		Pop outter tag of incoming double tagged packet and modify inner tag																			

+																					

+	Inject	eth 1/3	Outer 0x8100 + 6, Inner 0x8100 +3, SA000000112233, DA000000113355, V4																		

+	Output	eth 1/1	Tag 4, others not change																		

+																					

+	dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=3,vlan_vid=0x1006/0x1fff apply:pop_vlan,set_field=ofdpa_ovid:6 goto:11																				

+	dpctl tcp:192.168.1.1:6633 flow-mod table=11,cmd=add,prio=101 in_port=3,vlan_vid=0x1003/0x1fff,ofdpa_ovid=0x1006 apply:set_field=vlan_vid=4 goto:20																				

+	dpctl tcp:192.168.1.1:6633 flow-mod table=20,cmd=add,prio=201 in_port=3,vlan_vid=6/0xfff,eth_dst=00:00:00:11:33:55,eth_type=0x0800 goto:30																				

+	dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x40001 group=any,port=any,weight=0 output=1																				

+	dpctl tcp:192.168.1.1:6633 flow-mod table=60,cmd=add,prio=601 eth_type=0x0800,in_port=3 write:group=0x40001																				

+	dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x60003 group=any,port=any,weight=0 output=3																				

+	dpctl tcp:192.168.1.1:6633 flow-mod table=50,cmd=add,prio=501 vlan_vid=6,eth_dst=00:00:00:11:22:33 write:group=0x60003 goto:60																				

+															

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)    

+		

+        test_ports = sorted(config["port_map"].keys())	

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1006/0x1fff apply:pop_vlan,set_field=ofdpa_ovid:6 goto:11")

+        apply_dpctl_mod(self, config, "flow-mod table=11,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1003/0x1fff,ofdpa_ovid=0x1006 apply:set_field=vlan_vid=4 goto:20")

+        apply_dpctl_mod(self, config, "flow-mod table=20,cmd=add,prio=201 in_port="+str(input_port)+",vlan_vid=6/0xfff,eth_dst=00:00:00:11:33:55,eth_type=0x0800 goto:30")        

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x4000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "flow-mod table=60,cmd=add,prio=601 eth_type=0x0800,in_port="+str(input_port)+" write:group=0x4000"+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x60003 group=any,port=any,weight=0 output="+str(input_port))

+        apply_dpctl_mod(self, config, "flow-mod table=50,cmd=add,prio=501 vlan_vid=6,eth_dst=00:00:00:11:22:33 write:group=0x6000"+str(input_port)+" goto:60")

+

+        input_pkt = simple_packet(

+                '00 00 00 11 33 55 00 00 00 11 22 33 81 00 00 06 '

+                '81 00 00 03 08 00 45 00 00 2a 04 d2 00 00 7f 00 '

+                'b2 4b c0 a8 01 64 c0 a8 02 02 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        output_pkt = simple_packet(

+                '00 00 00 11 33 55 00 00 00 11 22 33 81 00 00 04 '

+                '08 00 45 00 00 2a 04 d2 00 00 7f 00 b2 4b c0 a8 '

+                '01 64 c0 a8 02 02 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)   

+

+

+

+class vlan_translate(base_tests.SimpleDataPlane):

+    """																					 

+	[VLAN tanslate]																				

+		Swap incoming tagged packet to a specified VLAN tag																			

+																					

+	Inject	eth 1/3	Tag 3, SA000000112233, DA000000113355, V4																		

+	Output	eth 1/1	Tag 5, others not change																		

+																					

+	dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=3,vlan_vid=0x1003/0x1fff apply:set_field=vlan_vid=5 goto:20																				

+	dpctl tcp:192.168.1.1:6633 flow-mod table=20,cmd=add,prio=201 in_port=3,vlan_vid=3/0xfff,eth_dst=00:00:00:11:33:55,eth_type=0x0800 goto:30																				

+	dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x50001 group=any,port=any,weight=0 output=1																				

+	dpctl tcp:192.168.1.1:6633 flow-mod table=60,cmd=add,prio=601 eth_type=0x0800,in_port=3 write:group=0x50001																				

+	dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x30003 group=any,port=any,weight=0 pop_vlan,output=3																				

+	dpctl tcp:192.168.1.1:6633 flow-mod table=50,cmd=add,prio=501 vlan_vid=3,eth_dst=00:00:00:11:22:33 write:group=0x30003 goto:60																				

+																		

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)    

+		

+        test_ports = sorted(config["port_map"].keys())	

+        input_port = test_ports[0]

+        output_port = test_ports[1]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1003/0x1fff apply:set_field=vlan_vid=5 goto:20")

+        apply_dpctl_mod(self, config, "flow-mod table=20,cmd=add,prio=201 in_port="+str(input_port)+",vlan_vid=3/0xfff,eth_dst=00:00:00:11:33:55,eth_type=0x0800 goto:30")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x5000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "flow-mod table=60,cmd=add,prio=601 eth_type=0x0800,in_port="+str(input_port)+" write:group=0x5000"+str(output_port))

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x3000"+str(input_port)+" group=any,port=any,weight=0 pop_vlan,output="+str(input_port))

+        apply_dpctl_mod(self, config, "flow-mod table=50,cmd=add,prio=501 vlan_vid=3,eth_dst=00:00:00:11:22:33 write:group=0x3000"+str(input_port)+" goto:60")

+

+        input_pkt = simple_packet(

+                '00 00 00 11 33 55 00 00 00 11 22 33 81 00 00 03 '

+                '08 00 45 00 00 2e 04 d2 00 00 7f 00 b2 47 c0 a8 '

+                '01 64 c0 a8 02 02 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        output_pkt = simple_packet(

+                '00 00 00 11 33 55 00 00 00 11 22 33 81 00 00 05 '

+                '08 00 45 00 00 2e 04 d2 00 00 7f 00 b2 47 c0 a8 '

+                '01 64 c0 a8 02 02 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        verify_packet(self, str(output_pkt), output_port)        
\ No newline at end of file
diff --git a/Fabric/Utilities/acctonUseDpctl/wred.py b/Fabric/Utilities/acctonUseDpctl/wred.py
new file mode 100755
index 0000000..0d12caa
--- /dev/null
+++ b/Fabric/Utilities/acctonUseDpctl/wred.py
@@ -0,0 +1,94 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+import logging

+import oftest.base_tests as base_tests

+from oftest import config

+from oftest.testutils import *

+from util import *

+from accton_util import convertIP4toStr as toIpV4Str

+from accton_util import convertMACtoStr as toMacStr

+

+"""

+Not Verify yet, need to think how to verify meter

+"""

+

+class wred(base_tests.SimpleDataPlane):

+    """

+    [WRED]

+      WRED (DCTCP)

+

+    Inject  eth 1/1 untag, SA000000112233, DA000000000111, TCP ECN 01 [100%]

+    Output  eth 1/5 ECN 11

+

+    [CLI] interface eth 1/1 => switch priority default 1

+    dpctl tcp:192.168.1.1:6633 group-mod cmd=add,type=ind,group=0x20005 group=any,port=any,weight=0 output=5

+    dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=1,vlan_vid=0x1000/0xfff apply:set_field=vlan_vid=2 goto:20

+    dpctl tcp:192.168.1.1:6633 flow-mod table=10,cmd=add,prio=101 in_port=3,vlan_vid=0x1000/0xfff apply:set_field=vlan_vid=2 goto:20

+    dpctl tcp:192.168.1.1:6633 flow-mod table=60,cmd=add,prio=601 in_port=3 write:group=0x20005

+    dpctl tcp:192.168.1.1:6633 flow-mod table=60,cmd=add,prio=601 eth_type=0x0800,in_port=1 write:group=0x20005

+    dpctl tcp:192.168.1.1:6633 queue-mod type=wred,port=5,queue=0 min=1,max=60,ecn=100,drop=100

+    """

+    def runTest(self):

+        delete_all_flows(self.controller)

+        delete_all_groups(self.controller)

+

+        test_ports = sorted(config["port_map"].keys())

+

+        input_port = test_ports[0]

+        input_port2 = test_ports[1]

+        output_port = test_ports[2]

+

+        apply_dpctl_mod(self, config, "meter-mod cmd=del,meter=0xffffffff")

+        apply_dpctl_mod(self, config, "group-mod cmd=add,type=ind,group=0x2000"+str(output_port)+" group=any,port=any,weight=0 output="+str(output_port))

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port)+",vlan_vid=0x1000/0xfff apply:set_field=vlan_vid=2 goto:20")

+        apply_dpctl_mod(self, config, "flow-mod table=10,cmd=add,prio=101 in_port="+str(input_port2)+",vlan_vid=0x1000/0xfff apply:set_field=vlan_vid=2 goto:20")

+        apply_dpctl_mod(self, config, "flow-mod table=60,cmd=add,prio=601 in_port="+str(input_port2)+" write:group=0x2000"+str(output_port))

+        apply_dpctl_mod(self, config, "flow-mod table=60,cmd=add,prio=601 eth_type=0x0800,in_port="+str(input_port)+" write:group=0x2000"+str(output_port))

+        apply_dpctl_mod(self, config, "flow-mod table=20,cmd=add,prio=201 vlan_vid=200/0xfff,eth_dst=00:00:00:00:02:00,eth_type=0x0800 goto:28")

+        apply_dpctl_mod(self, config, "queue-mod type=wred,port="+str(output_port)+",queue=0 min=1,max=60,ecn=100,drop=100")

+

+        # TCP ecn = 01

+        input_pkt = simple_packet(

+                '70 72 cf 7c f3 a3 00 00 00 11 22 33 81 00 00 02 '

+                '08 00 45 01 00 4e 04 d2 00 00 7f 06 b2 7b c0 a8 '

+                '01 0a c0 a8 02 02 00 03 00 06 00 01 f7 fa 00 00 '

+                '00 00 50 00 04 00 2f 5d 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        # TCP ecn = 00

+        input_pkt2 = simple_packet(

+                '70 72 cf 7c f3 a3 00 00 00 11 22 33 81 00 00 02 '

+                '08 00 45 00 00 4e 04 d2 00 00 7f 06 b2 7b c0 a8 '

+                '01 0a c0 a8 02 02 00 03 00 06 00 01 f7 fa 00 00 '

+                '00 00 50 00 04 00 2f 5d 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        # TCP ecn = 11

+        output_pkt = simple_packet(

+                '70 72 cf 7c f3 a3 00 00 00 11 22 33 81 00 00 02 '

+                '08 00 45 11 00 4e 04 d2 00 00 7f 06 b2 7b c0 a8 '

+                '01 0a c0 a8 02 02 00 03 00 06 00 01 f7 fa 00 00 '

+                '00 00 50 00 04 00 2f 5d 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '

+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00')

+

+        self.dataplane.send(input_port, str(input_pkt))

+        self.dataplane.send(input_port2, str(input_pkt2))

+        verify_packet(self, str(output_pkt), output_port)

+

diff --git a/Fabric/Utilities/platforms/bpp.py b/Fabric/Utilities/platforms/bpp.py
new file mode 100644
index 0000000..ba4e99a
--- /dev/null
+++ b/Fabric/Utilities/platforms/bpp.py
@@ -0,0 +1,89 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+"""
+Platform configuration file
+platform == bpp
+"""
+
+###############################################################################
+#
+# This platform assumes BPP VPI specifications on the command line. 
+#
+###############################################################################
+
+import sys
+import os
+import argparse
+import subprocess
+import dppv
+
+# The port specification is passed via the "--platform-args" option to OFTest. 
+# Note that we must guard against abbreviations supported by argparse
+if not "--platform-args" in " ".join(sys.argv):
+    raise Exception("--platform-args must be specified")
+
+ap = argparse.ArgumentParser("bpp")
+ap.add_argument("--platform-args")
+(ops, rest) = ap.parse_known_args()
+
+if not "@" in ops.platform_args:
+    # Assume it is just a device name. Get the ports from the track database. 
+    if "," in ops.platform_args:
+        (type_, d) = ops.platform_args.split(",")
+    else:
+        (type_, d) = ("udp", ops.platform_args)
+
+    trackScript = "/usr/bin/track"
+    if not os.path.exists(trackScript):
+        raise Exception("Cannot find the track script (looked at %s" % trackScript)
+
+    ports = eval("[" + subprocess.check_output([trackScript, "getports", d]) + "]")
+    ops.platform_args = type_ + "," + ",".join( "%s@%s:%s" % (p, d, p) for p in ports)
+
+    print "new platform_args: ", ops.platform_args
+    exit;
+#
+###############################################################################
+
+vpi_port_map = {}
+ports = ops.platform_args.split(",")
+bpptype = "udp"
+if ports[0] == "udp" or ports[0] == "tcp":
+    bpptype = ports.pop(0)
+
+for ps in ports:
+    (p, vpi) = ps.split("@")
+    vpi_port_map[int(p)] = "bpp|%s|%s" % (bpptype, vpi)
+
+print vpi_port_map; 
+
+def platform_config_update(config):
+    """
+    Update configuration for the remote platform
+
+    @param config The configuration dictionary to use/update
+    This routine defines the port map used for this configuration
+    """
+
+    global vpi_port_map
+    config["port_map"] = vpi_port_map.copy()
+    config["caps_table_idx"] = 0
+    #
+    # The class for DataPlanePorts must be specified here:
+    #
+    config['dataplane'] = { 'portclass': dppv.DataPlanePortVPI }
+    config['allow_user'] = True
diff --git a/Fabric/Utilities/platforms/dppv.py b/Fabric/Utilities/platforms/dppv.py
new file mode 100644
index 0000000..da7de65
--- /dev/null
+++ b/Fabric/Utilities/platforms/dppv.py
@@ -0,0 +1,95 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+###############################################################################
+#
+# DataPlanePort implementation for VPI platforms. 
+#
+# The VPI-based platforms available here (bpp and vpi) depend upon
+# this module for the implementation of the OFTest DataPlanePort interface. 
+#
+###############################################################################
+import sys
+import os
+import logging
+import time
+
+from oftest import config
+
+# Requires the libvpi and pyvpi packages
+from vpi import vpi
+
+class DataPlanePortVPI:
+    """
+    Class defining a port monitoring VPI object.
+
+    """
+    
+    #
+    # OFTest creates and destroys DataPlanePorts for each test. 
+    # We just cache them here. 
+    cachedVPIs = {}
+    
+    def vpiInit(self, interface_name, port_number, pcap_dir="."):
+        self.vpiSpec = interface_name; 
+        if self.vpiSpec in self.cachedVPIs:
+            self.vpi = self.cachedVPIs[self.vpiSpec]
+        else:
+            self.vpi = vpi.Vpi(self.vpiSpec)
+            pcapspec = "pcapdump|%s/oft-port%.2d.pcap|mpls|PORT%d" % (pcap_dir, port_number, port_number)
+            self.vpi.AddSendRecvListener(pcapspec); 
+            self.cachedVPIs[self.vpiSpec] = self.vpi
+
+        return self.vpi
+
+    
+    def __init__(self, interface_name, port_number):
+        """
+        Set up a port monitor object
+        @param interface_name The name of the physical interface like eth1
+        @param port_number The port number associated with this port
+        """
+        self.interface_name = interface_name
+        self.port_number = port_number
+        logname = "VPI:" + interface_name
+        self.logger = logging.getLogger(logname)
+        
+        path = "."
+        if config['log_file']:
+            path = config['log_file']
+
+        if self.vpiInit(interface_name, port_number, 
+                        os.path.dirname(os.path.abspath(path))) == None:
+            raise Exception("Could not create VPI interface %s" % interface_name)
+
+        self.logger.info("VPI: %s:%d\n" % (interface_name, port_number))
+
+    def fileno(self):
+        return self.vpi.DescriptorGet()
+
+    def recv(self):
+        pkt = self.vpi.Recv(False) 
+        return (pkt, time.time())
+
+    def send(self, packet):
+        """
+        Send a packet to the dataplane port
+        @param packet The packet data to send to the port
+        @retval The number of bytes sent
+        """
+        _len = len(packet); 
+        self.vpi.Send(packet)
+        return _len; 
diff --git a/Fabric/Utilities/platforms/eth.py b/Fabric/Utilities/platforms/eth.py
new file mode 100644
index 0000000..056edce
--- /dev/null
+++ b/Fabric/Utilities/platforms/eth.py
@@ -0,0 +1,44 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+"""
+Eth platform
+
+This platform uses the --interface command line option to choose the ethernet interfaces.
+"""
+
+def platform_config_update(config):
+    """
+    Update configuration for the local platform
+
+    @param config The configuration dictionary to use/update
+    """
+
+    port_map = {}
+
+    for (ofport, interface) in config["interfaces"]:
+        port_map[ofport] = interface
+
+    # Default to a veth configuration compatible with the reference switch
+    if not port_map:
+        port_map = {
+            1: 'veth1',
+            2: 'veth3',
+            3: 'veth5',
+            4: 'veth7',
+        }
+
+    config['port_map'] = port_map
diff --git a/Fabric/Utilities/platforms/local.py b/Fabric/Utilities/platforms/local.py
new file mode 100644
index 0000000..7caa1e5
--- /dev/null
+++ b/Fabric/Utilities/platforms/local.py
@@ -0,0 +1,38 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+"""
+Local platform
+
+This platform uses veth pairs to send packets to and from a userspace
+switch. The switch should be connected to veth0, veth2, veth4, and veth6.
+"""
+
+def platform_config_update(config):
+    """
+    Update configuration for the local platform
+
+    @param config The configuration dictionary to use/update
+    """
+    base_of_port = 1
+    base_if_index = 1
+    port_count = 4
+
+    port_map = {}
+    # Use every other veth interface (veth1, veth3, ...)
+    for idx in range(port_count):
+        port_map[base_of_port + idx] = "veth%d" % (base_if_index + 2 * idx)
+    config['port_map'] = port_map
diff --git a/Fabric/Utilities/platforms/ovs-dummy.py b/Fabric/Utilities/platforms/ovs-dummy.py
new file mode 100644
index 0000000..1d81091
--- /dev/null
+++ b/Fabric/Utilities/platforms/ovs-dummy.py
@@ -0,0 +1,155 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+"""
+Dummy platform
+
+This platform uses Open vSwitch dummy interfaces.
+"""
+
+import logging
+import os
+import select
+import socket
+import struct
+import sys
+import time
+from threading import Thread
+from threading import Lock
+
+RCV_TIMEOUT = 10000
+RUN_DIR = os.environ.get("OVS_RUNDIR", "/var/run/openvswitch")
+
+class DataPlanePortOVSDummy:
+    """
+    Class defining a port monitoring object that uses Unix domain
+    sockets for ports, intended for connecting to Open vSwitch "dummy"
+    netdevs.
+    """
+
+    def __init__(self, interface_name, port_number, max_pkts=1024):
+        """
+        Set up a port monitor object
+        @param interface_name The name of the physical interface like eth1
+        @param port_number The port number associated with this port
+        @param max_pkts Maximum number of pkts to keep in queue
+        """
+        self.interface_name = interface_name
+        self.max_pkts = max_pkts
+        self.port_number = port_number
+        self.txq = []
+        self.rxbuf = ""
+        logname = "dp-" + interface_name
+        self.logger = logging.getLogger(logname)
+        try:
+            self.socket = DataPlanePortOVSDummy.interface_open(interface_name)
+        except:
+            self.logger.info("Could not open socket")
+            raise
+        self.logger.info("Opened port monitor (class %s)", type(self).__name__)
+
+    @staticmethod
+    def interface_open(interface_name):
+        """
+        Open a Unix domain socket interface.
+        @param interface_name port name as a string such as 'eth1'
+        @retval s socket
+        """
+        s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+        s.settimeout(RCV_TIMEOUT)
+        s.setblocking(0)
+        s.connect("%s/%s" % (RUN_DIR, interface_name))
+        return s
+
+    def __del__(self):
+        if self.socket:
+            self.socket.close()
+
+    def fileno(self):
+        """
+        Return an integer file descriptor that can be passed to select(2).
+        """
+        return self.socket.fileno()
+
+    def recv(self):
+        while True:
+            rout, wout, eout = select.select([self.socket], [], [], 0)
+            if not rout:
+                return
+
+            if len(self.rxbuf) < 2:
+                n = 2 - len(self.rxbuf)
+            else:
+                frame_len = struct.unpack('>h', self.rxbuf[:2])[0]
+                n = (2 + frame_len) - len(self.rxbuf)
+
+            data = self.socket.recv(n)
+            self.rxbuf += data
+            if len(data) == n and len(self.rxbuf) > 2:
+                rcvtime = time.time()
+                packet = self.rxbuf[2:]
+                self.logger.debug("Pkt len " + str(len(packet)) +
+                         " in at " + str(rcvtime) + " on port " +
+                         str(self.port_number))
+                self.rxbuf = ""
+                return (packet, rcvtime)
+
+    def send(self, packet):
+        if len(self.txq) < self.max_pkts:
+            self.txq.append(struct.pack('>h', len(packet)) + packet)
+            retval = len(packet)
+        else:
+            retval = 0
+        self.__run_tx()
+        return retval
+
+    def __run_tx(self):
+        while self.txq:
+            rout, wout, eout = select.select([], [self.socket], [], 0)
+            if not wout:
+                return
+
+            retval = self.socket.send(self.txq[0])
+            if retval > 0:
+                self.txq[0] = self.txq[0][retval:]
+                if len(self.txq[0]) == 0:
+                    self.txq = self.txq[1:]
+        
+    def down(self):
+        pass
+
+    def up(self):
+        pass
+
+# Update this dictionary to suit your environment.
+dummy_port_map = {
+    1 : "p1",
+    2 : "p2",
+    3 : "p3",
+    4 : "p4"
+}
+
+def platform_config_update(config):
+    """
+    Update configuration for the dummy platform
+
+    @param config The configuration dictionary to use/update
+    """
+    global dummy_port_map
+    config["port_map"] = dummy_port_map.copy()
+    config["caps_table_idx"] = 0
+    config["dataplane"] = {"portclass": DataPlanePortOVSDummy}
+    config["allow_user"] = True
diff --git a/Fabric/Utilities/platforms/remote.py b/Fabric/Utilities/platforms/remote.py
new file mode 100644
index 0000000..95d1e25
--- /dev/null
+++ b/Fabric/Utilities/platforms/remote.py
@@ -0,0 +1,39 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+"""
+Remote platform
+
+This platform uses physical ethernet interfaces.
+"""
+
+# Update this dictionary to suit your environment.
+remote_port_map = {
+    23 : "eth2",
+    24 : "eth3",
+    25 : "eth4",
+    26 : "eth5"
+}
+
+def platform_config_update(config):
+    """
+    Update configuration for the remote platform
+
+    @param config The configuration dictionary to use/update
+    """
+    global remote_port_map
+    config["port_map"] = remote_port_map.copy()
+    config["caps_table_idx"] = 0
diff --git a/Fabric/Utilities/platforms/veth8.py b/Fabric/Utilities/platforms/veth8.py
new file mode 100644
index 0000000..665e250
--- /dev/null
+++ b/Fabric/Utilities/platforms/veth8.py
@@ -0,0 +1,39 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+"""
+veth8 platform
+
+This platform uses 8 veth pairs. The switch should connect to veth0, veth2, ..., veth14.
+"""
+
+def platform_config_update(config):
+    """
+    Update configuration for the local platform
+
+    @param config The configuration dictionary to use/update
+    """
+
+    config['port_map'] = {
+        1: 'veth1',
+        2: 'veth3',
+        3: 'veth5',
+        4: 'veth7',
+        5: 'veth9',
+        6: 'veth11',
+        7: 'veth13',
+        8: 'veth15',
+    }
diff --git a/Fabric/Utilities/platforms/vpip.py b/Fabric/Utilities/platforms/vpip.py
new file mode 100644
index 0000000..5efea77
--- /dev/null
+++ b/Fabric/Utilities/platforms/vpip.py
@@ -0,0 +1,65 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+"""
+Platform configuration file
+platform == vpi
+"""
+
+###############################################################################
+#
+# This platform module allows VPI port specifications on the command line. 
+#
+###############################################################################
+
+import sys
+import os
+import argparse
+import dppv
+
+# The port specification is passed via the "--platform-args" option to OFTest. 
+# Note that we must guard against abbreviations supported by argparse
+if not "--platform-args" in " ".join(sys.argv):
+    raise Exception("--platform-args must be specified")
+
+ap = argparse.ArgumentParser("vpi")
+ap.add_argument("--platform-args")
+(ops, rest) = ap.parse_known_args()
+
+vpi_port_map = {}
+ports = ops.platform_args.split(",")
+for ps in ports:
+    (p, vpi) = ps.split("@")
+    vpi_port_map[int(p)] = vpi
+
+print vpi_port_map; 
+
+def platform_config_update(config):
+    """
+    Update configuration for the remote platform
+
+    @param config The configuration dictionary to use/update
+    This routine defines the port map used for this configuration
+    """
+
+    global vpi_port_map
+    config["port_map"] = vpi_port_map.copy()
+    config["caps_table_idx"] = 0
+    #
+    # The class for DataPlanePorts must be specified here:
+    #
+    config['dataplane'] = { 'portclass': dppv.DataPlanePortVPI }
+    config['allow_user'] = True
diff --git a/Fabric/Utilities/src/python/.gitignore b/Fabric/Utilities/src/python/.gitignore
new file mode 100755
index 0000000..4b0053b
--- /dev/null
+++ b/Fabric/Utilities/src/python/.gitignore
@@ -0,0 +1,4 @@
+/build/
+/dist/
+/oftest.egg-info/
+*.pyc
diff --git a/Fabric/Utilities/src/python/loxi/LICENSE.pyloxi b/Fabric/Utilities/src/python/loxi/LICENSE.pyloxi
new file mode 100644
index 0000000..44ebddd
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/LICENSE.pyloxi
@@ -0,0 +1,36 @@
+OpenFlow Test Framework
+
+Copyright (c) 2010 The Board of Trustees of The Leland Stanford 
+Junior University
+
+Except where otherwise noted, this software is distributed under
+the OpenFlow Software License.  See 
+http://www.openflowswitch.org/wp/legal/ for current details.
+
+We are making the OpenFlow specification and associated documentation
+(Software) available for public use and benefit with the expectation
+that others will use, modify and enhance the Software and contribute
+those enhancements back to the community. However, since we would like
+to make the Software available for broadest use, with as few
+restrictions as possible permission is hereby granted, free of charge,
+to any person obtaining a copy of this Software to deal in the
+Software under the copyrights without restriction, including without
+limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions: 
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software. 
+
+THE SOFTWARE IS PROVIDED -Y´AS IS¡, WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 
+
+The name and trademarks of copyright holder(s) may NOT be used in
+advertising or publicity pertaining to the Software or any derivatives
+without specific, written prior permission. 
diff --git a/Fabric/Utilities/src/python/loxi/__init__.py b/Fabric/Utilities/src/python/loxi/__init__.py
new file mode 100644
index 0000000..088acb4
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/__init__.py
@@ -0,0 +1,85 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+# Automatically generated by LOXI from template toplevel_init.py
+# Do not modify
+
+version_names = {
+    1: "1.0",
+    2: "1.1",
+    3: "1.2",
+    4: "1.3",
+    5: "1.4",
+}
+
+def protocol(ver):
+    """
+    Import and return the protocol module for the given wire version.
+    """
+    if ver == 1:
+        import of10
+        return of10
+
+    if ver == 2:
+        import of11
+        return of11
+
+    if ver == 3:
+        import of12
+        return of12
+
+    if ver == 4:
+        import of13
+        return of13
+
+    if ver == 5:
+        import of14
+        return of14
+
+    raise ValueError
+
+class ProtocolError(Exception):
+    """
+    Raised when failing to deserialize an invalid OpenFlow message.
+    """
+    pass
+
+class Unimplemented(Exception):
+    """
+    Raised when an OpenFlow feature is not yet implemented in PyLoxi.
+    """
+    pass
+
+def unimplemented(msg):
+    raise Unimplemented(msg)
+
+class OFObject(object):
+    """
+    Superclass of all OpenFlow classes
+    """
+    def __init__(self, *args):
+        raise NotImplementedError("cannot instantiate abstract class")
+
+    def __ne__(self, other):
+        return not self.__eq__(other)
+
+    def show(self):
+        import loxi.pp
+        return loxi.pp.pp(self)
diff --git a/Fabric/Utilities/src/python/loxi/connection.py b/Fabric/Utilities/src/python/loxi/connection.py
new file mode 100644
index 0000000..2b1b5af
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/connection.py
@@ -0,0 +1,253 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright 2015, Big Switch Networks, Inc.
+
+"""
+OpenFlow connection class
+
+This class creates a thread which continually parses OpenFlow messages off the
+supplied socket and places them in a queue. The class has methods for reading messages
+from the RX queue, sending messages, and higher level operations like request-response
+and multipart transactions.
+"""
+
+import loxi
+import loxi.of14
+import logging
+import time
+import socket
+import errno
+import os
+import select
+from threading import Condition, Lock, Thread
+
+DEFAULT_TIMEOUT = 1
+
+class TransactionError(Exception):
+    def __str__(self):
+        return self.args[0]
+
+    @property
+    def msg(self):
+        return self.args[1]
+
+class Connection(Thread):
+    def __init__(self, sock):
+        Thread.__init__(self)
+        self.sock = sock
+        self.logger = logging.getLogger("connection")
+        self.rx = []
+        self.rx_cv = Condition()
+        self.tx_lock = Lock()
+        self.next_xid = 1
+        self.wakeup_rd, self.wakeup_wr = os.pipe()
+        self.finished = False
+        self.read_buffer = None
+
+    def run(self):
+        while not self.finished:
+            rd, wr, err = select.select([self.sock, self.wakeup_rd], [], [])
+            if self.sock in rd:
+                self.process_read()
+            if self.wakeup_rd in rd:
+                os.read(self.wakeup_rd, 1)
+        self.logger.debug("Exited event loop")
+
+    def process_read(self):
+        recvd = self.sock.recv(4096)
+
+        self.logger.debug("Received %d bytes", len(recvd))
+
+        buf = self.read_buffer
+        if buf:
+            buf += recvd
+        else:
+            buf = recvd
+
+        offset = 0
+        while offset < len(buf):
+            if offset + 8 > len(buf):
+                # Not enough data for the OpenFlow header
+                break
+
+            # Parse the header to get type
+            hdr_version, hdr_type, hdr_msglen, hdr_xid = loxi.of14.message.parse_header(buf[offset:])
+
+            # Use loxi to resolve ofp of matching version
+            ofp = loxi.protocol(hdr_version)
+
+            # Extract the raw message bytes
+            if (offset + hdr_msglen) > len(buf):
+                # Not enough data for the body
+                break
+            rawmsg = buf[offset : offset + hdr_msglen]
+            offset += hdr_msglen
+
+            msg = ofp.message.parse_message(rawmsg)
+            if not msg:
+                self.logger.warn("Could not parse message")
+                continue
+
+            self.logger.debug("Received message %s.%s xid %d length %d",
+                              type(msg).__module__, type(msg).__name__, hdr_xid, hdr_msglen)
+
+            with self.rx_cv:
+                self.rx.append(msg)
+                self.rx_cv.notify_all()
+
+        if offset == len(buf):
+            self.read_buffer = None
+        else:
+            self.read_buffer = buf[offset:]
+            self.logger.debug("%d bytes remaining", len(self.read_buffer))
+
+    def recv(self, predicate, timeout=DEFAULT_TIMEOUT):
+        """
+        Remove and return the first message in the RX queue for
+        which 'predicate' returns true
+        """
+        assert self.is_alive()
+
+        deadline = time.time() + timeout
+        while True:
+            with self.rx_cv:
+                for i, msg in enumerate(self.rx):
+                    if predicate(msg):
+                        return self.rx.pop(i)
+
+                now = time.time()
+                if now > deadline:
+                    return None
+                else:
+                    self.rx_cv.wait(deadline - now)
+
+    def recv_any(self, timeout=DEFAULT_TIMEOUT):
+        """
+        Return the first message in the RX queue
+        """
+        return self.recv(lambda msg: True, timeout)
+
+    def recv_xid(self, xid, timeout=DEFAULT_TIMEOUT):
+        """
+        Return the first message in the RX queue with XID 'xid'
+        """
+        return self.recv(lambda msg: msg.xid == xid, timeout)
+
+    def recv_class(self, klass, timeout=DEFAULT_TIMEOUT):
+        """
+        Return the first message in the RX queue which is an instance of 'klass'
+        """
+        return self.recv(lambda msg: isinstance(msg, klass), timeout)
+
+    def send_raw(self, buf):
+        """
+        Send raw bytes on the socket
+        """
+        assert self.is_alive()
+        self.logger.debug("Sending raw message length %d", len(buf))
+        with self.tx_lock:
+            if self.sock.sendall(buf) is not None:
+                raise RuntimeError("failed to send message to switch")
+
+    def send(self, msg):
+        """
+        Send a message
+        """
+        assert self.is_alive()
+
+        if msg.xid is None:
+            msg.xid = self._gen_xid()
+        buf = msg.pack()
+        self.logger.debug("Sending message %s.%s xid %d length %d",
+                          type(msg).__module__, type(msg).__name__, msg.xid, len(buf))
+        with self.tx_lock:
+            if self.sock.sendall(buf) is not None:
+                raise RuntimeError("failed to send message to switch")
+
+    def transact(self, msg, timeout=DEFAULT_TIMEOUT):
+        """
+        Send a message and return the reply
+        """
+        self.send(msg)
+        reply = self.recv_xid(msg.xid, timeout)
+        if reply is None:
+            raise TransactionError("no reply for %s" % type(msg).__name__, None)
+        elif isinstance(reply, loxi.protocol(reply.version).message.error_msg):
+            raise TransactionError("received %s in response to %s" % (type(reply).__name__, type(msg).__name__), reply)
+        return reply
+
+    def transact_multipart_generator(self, msg, timeout=DEFAULT_TIMEOUT):
+        """
+        Send a multipart request and yield each entry from the replies
+        """
+        self.send(msg)
+        finished = False
+        while not finished:
+            reply = self.recv_xid(msg.xid, timeout)
+            if reply is None:
+                raise TransactionError("no reply for %s" % type(msg).__name__, None)
+            elif not isinstance(reply, loxi.protocol(reply.version).message.stats_reply):
+                raise TransactionError("received %s in response to %s" % (type(reply).__name__, type(msg).__name__), reply)
+            for entry in reply.entries:
+                yield entry
+            finished = reply.flags & loxi.protocol(reply.version).OFPSF_REPLY_MORE == 0
+
+    def transact_multipart(self, msg, timeout=DEFAULT_TIMEOUT):
+        """
+        Send a multipart request and return all entries from the replies
+        """
+        entries = []
+        for entry in self.transact_multipart_generator(msg, timeout):
+            entries.append(entry)
+        return entries
+
+    def stop(self):
+        """
+        Signal the thread to exit and wait for it
+        """
+        assert not self.finished
+        self.logger.debug("Stopping connection")
+        self.finished = True
+        os.write(self.wakeup_wr, "x")
+        self.join()
+        self.sock.close()
+        os.close(self.wakeup_rd)
+        os.close(self.wakeup_wr)
+        self.logger.debug("Stopped connection")
+
+    def _gen_xid(self):
+        xid = self.next_xid
+        self.next_xid += 1
+        return xid
+
+def connect(ip, port=6653, daemon=True, ofp=loxi.of14):
+    """
+    Actively connect to a switch
+    """
+    soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+    soc.connect((ip, port))
+    soc.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, True)
+    cxn = Connection(soc)
+    cxn.daemon = daemon
+    cxn.logger.debug("Connected to %s:%d", ip, port)
+    cxn.start()
+
+    cxn.send(ofp.message.hello())
+    if not cxn.recv(lambda msg: msg.type == ofp.OFPT_HELLO):
+        raise Exception("Did not receive HELLO")
+
+    return cxn
diff --git a/Fabric/Utilities/src/python/loxi/generic_util.py b/Fabric/Utilities/src/python/loxi/generic_util.py
new file mode 100644
index 0000000..90aa672
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/generic_util.py
@@ -0,0 +1,116 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+"""
+Utility functions independent of the protocol version
+"""
+
+# Automatically generated by LOXI from template generic_util.py
+# Do not modify
+
+import loxi
+import struct
+
+def pack_list(values):
+    return "".join([x.pack() for x in values])
+
+def unpack_list(reader, deserializer):
+    """
+    The deserializer function should take an OFReader and return the new object.
+    """
+    entries = []
+    while not reader.is_empty():
+        entries.append(deserializer(reader))
+    return entries
+
+def pad_to(alignment, length):
+    """
+    Return a string of zero bytes that will pad a string of length 'length' to
+    a multiple of 'alignment'.
+    """
+    return "\x00" * ((length + alignment - 1)/alignment*alignment - length)
+
+class OFReader(object):
+    """
+    Cursor over a read-only buffer
+
+    OpenFlow messages are best thought of as a sequence of elements of
+    variable size, rather than a C-style struct with fixed offsets and
+    known field lengths. This class supports efficiently reading
+    fields sequentially and is intended to be used recursively by the
+    parsers of child objects which will implicitly update the offset.
+
+    buf: buffer object
+    start: initial position in the buffer
+    length: number of bytes after start
+    offset: distance from start
+    """
+    def __init__(self, buf, start=0, length=None):
+        self.buf = buf
+        self.start = start
+        if length is None:
+            self.length = len(buf) - start
+        else:
+            self.length = length
+        self.offset = 0
+
+    def read(self, fmt):
+        st = struct.Struct(fmt)
+        if self.offset + st.size > self.length:
+            raise loxi.ProtocolError("Buffer too short")
+        result = st.unpack_from(self.buf, self.start+self.offset)
+        self.offset += st.size
+        return result
+
+    def read_all(self):
+        s = self.buf[(self.start+self.offset):(self.start+self.length)]
+        assert(len(s) == self.length - self.offset)
+        self.offset = self.length
+        return s
+
+    def peek(self, fmt, offset=0):
+        st = struct.Struct(fmt)
+        if self.offset + offset + st.size > self.length:
+            raise loxi.ProtocolError("Buffer too short")
+        result = st.unpack_from(self.buf, self.start + self.offset + offset)
+        return result
+
+    def skip(self, length):
+        if self.offset + length > self.length:
+            raise loxi.ProtocolError("Buffer too short")
+        self.offset += length
+
+    def skip_align(self):
+        new_offset = (self.offset + 7) / 8 * 8
+        if new_offset > self.length:
+            raise loxi.ProtocolError("Buffer too short")
+        self.offset = new_offset
+
+    def is_empty(self):
+        return self.offset == self.length
+
+    # Used when parsing objects that have their own length fields
+    def slice(self, length, rewind=0):
+        if self.offset + length - rewind > self.length:
+            raise loxi.ProtocolError("Buffer too short")
+        reader = OFReader(self.buf, self.start + self.offset - rewind, length)
+        reader.skip(rewind)
+        self.offset += length - rewind
+        return reader
diff --git a/Fabric/Utilities/src/python/loxi/of10/__init__.py b/Fabric/Utilities/src/python/loxi/of10/__init__.py
new file mode 100644
index 0000000..514c207
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of10/__init__.py
@@ -0,0 +1,31 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template init.py
+# Do not modify
+
+import const
+import action
+import message
+import common
+from const import *
+from common import *
+from loxi import ProtocolError
diff --git a/Fabric/Utilities/src/python/loxi/of10/action.py b/Fabric/Utilities/src/python/loxi/of10/action.py
new file mode 100644
index 0000000..c9f479b
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of10/action.py
@@ -0,0 +1,1091 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of10']
+
+class action(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = action.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = action()
+        obj.type = reader.read("!H")[0]
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("action {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class experimenter(action):
+    subtypes = {}
+
+    type = 65535
+
+    def __init__(self, experimenter=None, data=None):
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 4)
+        subclass = experimenter.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = experimenter()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.experimenter = reader.read("!L")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.experimenter != other.experimenter: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[65535] = experimenter
+
+class bsn(experimenter):
+    subtypes = {}
+
+    type = 65535
+    experimenter = 6035143
+
+    def __init__(self, subtype=None):
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 8)
+        subclass = bsn.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = bsn()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        obj.subtype = reader.read("!L")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+experimenter.subtypes[6035143] = bsn
+
+class bsn_checksum(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 4
+
+    def __init__(self, checksum=None):
+        if checksum != None:
+            self.checksum = checksum
+        else:
+            self.checksum = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(util.pack_checksum_128(self.checksum))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_checksum()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 4)
+        obj.checksum = util.unpack_checksum_128(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.checksum != other.checksum: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_checksum {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("checksum = ");
+                q.pp(self.checksum)
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[4] = bsn_checksum
+
+class bsn_mirror(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 1
+
+    def __init__(self, dest_port=None, vlan_tag=None, copy_stage=None):
+        if dest_port != None:
+            self.dest_port = dest_port
+        else:
+            self.dest_port = 0
+        if vlan_tag != None:
+            self.vlan_tag = vlan_tag
+        else:
+            self.vlan_tag = 0
+        if copy_stage != None:
+            self.copy_stage = copy_stage
+        else:
+            self.copy_stage = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.dest_port))
+        packed.append(struct.pack("!L", self.vlan_tag))
+        packed.append(struct.pack("!B", self.copy_stage))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_mirror()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 1)
+        obj.dest_port = reader.read("!L")[0]
+        obj.vlan_tag = reader.read("!L")[0]
+        obj.copy_stage = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.dest_port != other.dest_port: return False
+        if self.vlan_tag != other.vlan_tag: return False
+        if self.copy_stage != other.copy_stage: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_mirror {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("dest_port = ");
+                q.text("%#x" % self.dest_port)
+                q.text(","); q.breakable()
+                q.text("vlan_tag = ");
+                q.text("%#x" % self.vlan_tag)
+                q.text(","); q.breakable()
+                q.text("copy_stage = ");
+                q.text("%#x" % self.copy_stage)
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[1] = bsn_mirror
+
+class bsn_set_tunnel_dst(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 2
+
+    def __init__(self, dst=None):
+        if dst != None:
+            self.dst = dst
+        else:
+            self.dst = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.dst))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_tunnel_dst()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 2)
+        obj.dst = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.dst != other.dst: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_tunnel_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("dst = ");
+                q.text("%#x" % self.dst)
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[2] = bsn_set_tunnel_dst
+
+class enqueue(action):
+    type = 11
+
+    def __init__(self, port=None, queue_id=None):
+        if port != None:
+            self.port = port
+        else:
+            self.port = 0
+        if queue_id != None:
+            self.queue_id = queue_id
+        else:
+            self.queue_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(util.pack_port_no(self.port))
+        packed.append('\x00' * 6)
+        packed.append(struct.pack("!L", self.queue_id))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = enqueue()
+        _type = reader.read("!H")[0]
+        assert(_type == 11)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.port = util.unpack_port_no(reader)
+        reader.skip(6)
+        obj.queue_id = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.port != other.port: return False
+        if self.queue_id != other.queue_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("enqueue {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("port = ");
+                q.text(util.pretty_port(self.port))
+                q.text(","); q.breakable()
+                q.text("queue_id = ");
+                q.text("%#x" % self.queue_id)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[11] = enqueue
+
+class nicira(experimenter):
+    subtypes = {}
+
+    type = 65535
+    experimenter = 8992
+
+    def __init__(self, subtype=None):
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!H", self.subtype))
+        packed.append('\x00' * 2)
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 8)
+        subclass = nicira.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = nicira()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 8992)
+        obj.subtype = reader.read("!H")[0]
+        reader.skip(2)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("nicira {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+experimenter.subtypes[8992] = nicira
+
+class nicira_dec_ttl(nicira):
+    type = 65535
+    experimenter = 8992
+    subtype = 18
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!H", self.subtype))
+        packed.append('\x00' * 2)
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = nicira_dec_ttl()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 8992)
+        _subtype = reader.read("!H")[0]
+        assert(_subtype == 18)
+        reader.skip(2)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("nicira_dec_ttl {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+nicira.subtypes[18] = nicira_dec_ttl
+
+class output(action):
+    type = 0
+
+    def __init__(self, port=None, max_len=None):
+        if port != None:
+            self.port = port
+        else:
+            self.port = 0
+        if max_len != None:
+            self.max_len = max_len
+        else:
+            self.max_len = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(util.pack_port_no(self.port))
+        packed.append(struct.pack("!H", self.max_len))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = output()
+        _type = reader.read("!H")[0]
+        assert(_type == 0)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.port = util.unpack_port_no(reader)
+        obj.max_len = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.port != other.port: return False
+        if self.max_len != other.max_len: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("output {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("port = ");
+                q.text(util.pretty_port(self.port))
+                q.text(","); q.breakable()
+                q.text("max_len = ");
+                q.text("%#x" % self.max_len)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[0] = output
+
+class set_dl_dst(action):
+    type = 5
+
+    def __init__(self, dl_addr=None):
+        if dl_addr != None:
+            self.dl_addr = dl_addr
+        else:
+            self.dl_addr = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!6B", *self.dl_addr))
+        packed.append('\x00' * 6)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_dl_dst()
+        _type = reader.read("!H")[0]
+        assert(_type == 5)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.dl_addr = list(reader.read('!6B'))
+        reader.skip(6)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.dl_addr != other.dl_addr: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_dl_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("dl_addr = ");
+                q.text(util.pretty_mac(self.dl_addr))
+            q.breakable()
+        q.text('}')
+
+action.subtypes[5] = set_dl_dst
+
+class set_dl_src(action):
+    type = 4
+
+    def __init__(self, dl_addr=None):
+        if dl_addr != None:
+            self.dl_addr = dl_addr
+        else:
+            self.dl_addr = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!6B", *self.dl_addr))
+        packed.append('\x00' * 6)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_dl_src()
+        _type = reader.read("!H")[0]
+        assert(_type == 4)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.dl_addr = list(reader.read('!6B'))
+        reader.skip(6)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.dl_addr != other.dl_addr: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_dl_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("dl_addr = ");
+                q.text(util.pretty_mac(self.dl_addr))
+            q.breakable()
+        q.text('}')
+
+action.subtypes[4] = set_dl_src
+
+class set_nw_dst(action):
+    type = 7
+
+    def __init__(self, nw_addr=None):
+        if nw_addr != None:
+            self.nw_addr = nw_addr
+        else:
+            self.nw_addr = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.nw_addr))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_nw_dst()
+        _type = reader.read("!H")[0]
+        assert(_type == 7)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.nw_addr = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.nw_addr != other.nw_addr: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_nw_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("nw_addr = ");
+                q.text("%#x" % self.nw_addr)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[7] = set_nw_dst
+
+class set_nw_src(action):
+    type = 6
+
+    def __init__(self, nw_addr=None):
+        if nw_addr != None:
+            self.nw_addr = nw_addr
+        else:
+            self.nw_addr = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.nw_addr))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_nw_src()
+        _type = reader.read("!H")[0]
+        assert(_type == 6)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.nw_addr = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.nw_addr != other.nw_addr: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_nw_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("nw_addr = ");
+                q.text("%#x" % self.nw_addr)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[6] = set_nw_src
+
+class set_nw_tos(action):
+    type = 8
+
+    def __init__(self, nw_tos=None):
+        if nw_tos != None:
+            self.nw_tos = nw_tos
+        else:
+            self.nw_tos = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!B", self.nw_tos))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_nw_tos()
+        _type = reader.read("!H")[0]
+        assert(_type == 8)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.nw_tos = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.nw_tos != other.nw_tos: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_nw_tos {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("nw_tos = ");
+                q.text("%#x" % self.nw_tos)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[8] = set_nw_tos
+
+class set_tp_dst(action):
+    type = 10
+
+    def __init__(self, tp_port=None):
+        if tp_port != None:
+            self.tp_port = tp_port
+        else:
+            self.tp_port = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!H", self.tp_port))
+        packed.append('\x00' * 2)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_tp_dst()
+        _type = reader.read("!H")[0]
+        assert(_type == 10)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.tp_port = reader.read("!H")[0]
+        reader.skip(2)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.tp_port != other.tp_port: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_tp_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("tp_port = ");
+                q.text("%#x" % self.tp_port)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[10] = set_tp_dst
+
+class set_tp_src(action):
+    type = 9
+
+    def __init__(self, tp_port=None):
+        if tp_port != None:
+            self.tp_port = tp_port
+        else:
+            self.tp_port = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!H", self.tp_port))
+        packed.append('\x00' * 2)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_tp_src()
+        _type = reader.read("!H")[0]
+        assert(_type == 9)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.tp_port = reader.read("!H")[0]
+        reader.skip(2)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.tp_port != other.tp_port: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_tp_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("tp_port = ");
+                q.text("%#x" % self.tp_port)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[9] = set_tp_src
+
+class set_vlan_pcp(action):
+    type = 2
+
+    def __init__(self, vlan_pcp=None):
+        if vlan_pcp != None:
+            self.vlan_pcp = vlan_pcp
+        else:
+            self.vlan_pcp = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!B", self.vlan_pcp))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_vlan_pcp()
+        _type = reader.read("!H")[0]
+        assert(_type == 2)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.vlan_pcp = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.vlan_pcp != other.vlan_pcp: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_vlan_pcp {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("vlan_pcp = ");
+                q.text("%#x" % self.vlan_pcp)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[2] = set_vlan_pcp
+
+class set_vlan_vid(action):
+    type = 1
+
+    def __init__(self, vlan_vid=None):
+        if vlan_vid != None:
+            self.vlan_vid = vlan_vid
+        else:
+            self.vlan_vid = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!H", self.vlan_vid))
+        packed.append('\x00' * 2)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_vlan_vid()
+        _type = reader.read("!H")[0]
+        assert(_type == 1)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.vlan_vid = reader.read("!H")[0]
+        reader.skip(2)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.vlan_vid != other.vlan_vid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_vlan_vid {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("vlan_vid = ");
+                q.text("%#x" % self.vlan_vid)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[1] = set_vlan_vid
+
+class strip_vlan(action):
+    type = 3
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = strip_vlan()
+        _type = reader.read("!H")[0]
+        assert(_type == 3)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("strip_vlan {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action.subtypes[3] = strip_vlan
+
+
diff --git a/Fabric/Utilities/src/python/loxi/of10/common.py b/Fabric/Utilities/src/python/loxi/of10/common.py
new file mode 100644
index 0000000..8d43657
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of10/common.py
@@ -0,0 +1,1315 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of10']
+
+class bsn_interface(loxi.OFObject):
+
+    def __init__(self, hw_addr=None, name=None, ipv4_addr=None, ipv4_netmask=None):
+        if hw_addr != None:
+            self.hw_addr = hw_addr
+        else:
+            self.hw_addr = [0,0,0,0,0,0]
+        if name != None:
+            self.name = name
+        else:
+            self.name = ""
+        if ipv4_addr != None:
+            self.ipv4_addr = ipv4_addr
+        else:
+            self.ipv4_addr = 0
+        if ipv4_netmask != None:
+            self.ipv4_netmask = ipv4_netmask
+        else:
+            self.ipv4_netmask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!6B", *self.hw_addr))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!16s", self.name))
+        packed.append(struct.pack("!L", self.ipv4_addr))
+        packed.append(struct.pack("!L", self.ipv4_netmask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_interface()
+        obj.hw_addr = list(reader.read('!6B'))
+        reader.skip(2)
+        obj.name = reader.read("!16s")[0].rstrip("\x00")
+        obj.ipv4_addr = reader.read("!L")[0]
+        obj.ipv4_netmask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.hw_addr != other.hw_addr: return False
+        if self.name != other.name: return False
+        if self.ipv4_addr != other.ipv4_addr: return False
+        if self.ipv4_netmask != other.ipv4_netmask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_interface {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("hw_addr = ");
+                q.text(util.pretty_mac(self.hw_addr))
+                q.text(","); q.breakable()
+                q.text("name = ");
+                q.pp(self.name)
+                q.text(","); q.breakable()
+                q.text("ipv4_addr = ");
+                q.text(util.pretty_ipv4(self.ipv4_addr))
+                q.text(","); q.breakable()
+                q.text("ipv4_netmask = ");
+                q.text(util.pretty_ipv4(self.ipv4_netmask))
+            q.breakable()
+        q.text('}')
+
+
+class bsn_vport(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = bsn_vport.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = bsn_vport()
+        obj.type = reader.read("!H")[0]
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vport {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class bsn_vport_l2gre(bsn_vport):
+    type = 1
+
+    def __init__(self, flags=None, port_no=None, loopback_port_no=None, local_mac=None, nh_mac=None, src_ip=None, dst_ip=None, dscp=None, ttl=None, vpn=None, rate_limit=None, if_name=None):
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if loopback_port_no != None:
+            self.loopback_port_no = loopback_port_no
+        else:
+            self.loopback_port_no = 0
+        if local_mac != None:
+            self.local_mac = local_mac
+        else:
+            self.local_mac = [0,0,0,0,0,0]
+        if nh_mac != None:
+            self.nh_mac = nh_mac
+        else:
+            self.nh_mac = [0,0,0,0,0,0]
+        if src_ip != None:
+            self.src_ip = src_ip
+        else:
+            self.src_ip = 0
+        if dst_ip != None:
+            self.dst_ip = dst_ip
+        else:
+            self.dst_ip = 0
+        if dscp != None:
+            self.dscp = dscp
+        else:
+            self.dscp = 0
+        if ttl != None:
+            self.ttl = ttl
+        else:
+            self.ttl = 0
+        if vpn != None:
+            self.vpn = vpn
+        else:
+            self.vpn = 0
+        if rate_limit != None:
+            self.rate_limit = rate_limit
+        else:
+            self.rate_limit = 0
+        if if_name != None:
+            self.if_name = if_name
+        else:
+            self.if_name = ""
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.flags))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(util.pack_port_no(self.loopback_port_no))
+        packed.append(struct.pack("!6B", *self.local_mac))
+        packed.append(struct.pack("!6B", *self.nh_mac))
+        packed.append(struct.pack("!L", self.src_ip))
+        packed.append(struct.pack("!L", self.dst_ip))
+        packed.append(struct.pack("!B", self.dscp))
+        packed.append(struct.pack("!B", self.ttl))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!L", self.vpn))
+        packed.append(struct.pack("!L", self.rate_limit))
+        packed.append(struct.pack("!16s", self.if_name))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vport_l2gre()
+        _type = reader.read("!H")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.flags = reader.read("!L")[0]
+        obj.port_no = util.unpack_port_no(reader)
+        obj.loopback_port_no = util.unpack_port_no(reader)
+        obj.local_mac = list(reader.read('!6B'))
+        obj.nh_mac = list(reader.read('!6B'))
+        obj.src_ip = reader.read("!L")[0]
+        obj.dst_ip = reader.read("!L")[0]
+        obj.dscp = reader.read("!B")[0]
+        obj.ttl = reader.read("!B")[0]
+        reader.skip(2)
+        obj.vpn = reader.read("!L")[0]
+        obj.rate_limit = reader.read("!L")[0]
+        obj.if_name = reader.read("!16s")[0].rstrip("\x00")
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.flags != other.flags: return False
+        if self.port_no != other.port_no: return False
+        if self.loopback_port_no != other.loopback_port_no: return False
+        if self.local_mac != other.local_mac: return False
+        if self.nh_mac != other.nh_mac: return False
+        if self.src_ip != other.src_ip: return False
+        if self.dst_ip != other.dst_ip: return False
+        if self.dscp != other.dscp: return False
+        if self.ttl != other.ttl: return False
+        if self.vpn != other.vpn: return False
+        if self.rate_limit != other.rate_limit: return False
+        if self.if_name != other.if_name: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vport_l2gre {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("loopback_port_no = ");
+                q.text(util.pretty_port(self.loopback_port_no))
+                q.text(","); q.breakable()
+                q.text("local_mac = ");
+                q.text(util.pretty_mac(self.local_mac))
+                q.text(","); q.breakable()
+                q.text("nh_mac = ");
+                q.text(util.pretty_mac(self.nh_mac))
+                q.text(","); q.breakable()
+                q.text("src_ip = ");
+                q.text(util.pretty_ipv4(self.src_ip))
+                q.text(","); q.breakable()
+                q.text("dst_ip = ");
+                q.text(util.pretty_ipv4(self.dst_ip))
+                q.text(","); q.breakable()
+                q.text("dscp = ");
+                q.text("%#x" % self.dscp)
+                q.text(","); q.breakable()
+                q.text("ttl = ");
+                q.text("%#x" % self.ttl)
+                q.text(","); q.breakable()
+                q.text("vpn = ");
+                q.text("%#x" % self.vpn)
+                q.text(","); q.breakable()
+                q.text("rate_limit = ");
+                q.text("%#x" % self.rate_limit)
+                q.text(","); q.breakable()
+                q.text("if_name = ");
+                q.pp(self.if_name)
+            q.breakable()
+        q.text('}')
+
+bsn_vport.subtypes[1] = bsn_vport_l2gre
+
+class bsn_vport_q_in_q(bsn_vport):
+    type = 0
+
+    def __init__(self, port_no=None, ingress_tpid=None, ingress_vlan_id=None, egress_tpid=None, egress_vlan_id=None, if_name=None):
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if ingress_tpid != None:
+            self.ingress_tpid = ingress_tpid
+        else:
+            self.ingress_tpid = 0
+        if ingress_vlan_id != None:
+            self.ingress_vlan_id = ingress_vlan_id
+        else:
+            self.ingress_vlan_id = 0
+        if egress_tpid != None:
+            self.egress_tpid = egress_tpid
+        else:
+            self.egress_tpid = 0
+        if egress_vlan_id != None:
+            self.egress_vlan_id = egress_vlan_id
+        else:
+            self.egress_vlan_id = 0
+        if if_name != None:
+            self.if_name = if_name
+        else:
+            self.if_name = ""
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.port_no))
+        packed.append(struct.pack("!H", self.ingress_tpid))
+        packed.append(struct.pack("!H", self.ingress_vlan_id))
+        packed.append(struct.pack("!H", self.egress_tpid))
+        packed.append(struct.pack("!H", self.egress_vlan_id))
+        packed.append(struct.pack("!16s", self.if_name))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vport_q_in_q()
+        _type = reader.read("!H")[0]
+        assert(_type == 0)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.port_no = reader.read("!L")[0]
+        obj.ingress_tpid = reader.read("!H")[0]
+        obj.ingress_vlan_id = reader.read("!H")[0]
+        obj.egress_tpid = reader.read("!H")[0]
+        obj.egress_vlan_id = reader.read("!H")[0]
+        obj.if_name = reader.read("!16s")[0].rstrip("\x00")
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.port_no != other.port_no: return False
+        if self.ingress_tpid != other.ingress_tpid: return False
+        if self.ingress_vlan_id != other.ingress_vlan_id: return False
+        if self.egress_tpid != other.egress_tpid: return False
+        if self.egress_vlan_id != other.egress_vlan_id: return False
+        if self.if_name != other.if_name: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vport_q_in_q {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("port_no = ");
+                q.text("%#x" % self.port_no)
+                q.text(","); q.breakable()
+                q.text("ingress_tpid = ");
+                q.text("%#x" % self.ingress_tpid)
+                q.text(","); q.breakable()
+                q.text("ingress_vlan_id = ");
+                q.text("%#x" % self.ingress_vlan_id)
+                q.text(","); q.breakable()
+                q.text("egress_tpid = ");
+                q.text("%#x" % self.egress_tpid)
+                q.text(","); q.breakable()
+                q.text("egress_vlan_id = ");
+                q.text("%#x" % self.egress_vlan_id)
+                q.text(","); q.breakable()
+                q.text("if_name = ");
+                q.pp(self.if_name)
+            q.breakable()
+        q.text('}')
+
+bsn_vport.subtypes[0] = bsn_vport_q_in_q
+
+class flow_stats_entry(loxi.OFObject):
+
+    def __init__(self, table_id=None, match=None, duration_sec=None, duration_nsec=None, priority=None, idle_timeout=None, hard_timeout=None, cookie=None, packet_count=None, byte_count=None, actions=None):
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if duration_sec != None:
+            self.duration_sec = duration_sec
+        else:
+            self.duration_sec = 0
+        if duration_nsec != None:
+            self.duration_nsec = duration_nsec
+        else:
+            self.duration_nsec = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if packet_count != None:
+            self.packet_count = packet_count
+        else:
+            self.packet_count = 0
+        if byte_count != None:
+            self.byte_count = byte_count
+        else:
+            self.byte_count = 0
+        if actions != None:
+            self.actions = actions
+        else:
+            self.actions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 0
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append('\x00' * 1)
+        packed.append(self.match.pack())
+        packed.append(struct.pack("!L", self.duration_sec))
+        packed.append(struct.pack("!L", self.duration_nsec))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append('\x00' * 6)
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.packet_count))
+        packed.append(struct.pack("!Q", self.byte_count))
+        packed.append(loxi.generic_util.pack_list(self.actions))
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_stats_entry()
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 2)
+        obj.table_id = reader.read("!B")[0]
+        reader.skip(1)
+        obj.match = ofp.match.unpack(reader)
+        obj.duration_sec = reader.read("!L")[0]
+        obj.duration_nsec = reader.read("!L")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        reader.skip(6)
+        obj.cookie = reader.read("!Q")[0]
+        obj.packet_count = reader.read("!Q")[0]
+        obj.byte_count = reader.read("!Q")[0]
+        obj.actions = loxi.generic_util.unpack_list(reader, ofp.action.action.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.table_id != other.table_id: return False
+        if self.match != other.match: return False
+        if self.duration_sec != other.duration_sec: return False
+        if self.duration_nsec != other.duration_nsec: return False
+        if self.priority != other.priority: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.cookie != other.cookie: return False
+        if self.packet_count != other.packet_count: return False
+        if self.byte_count != other.byte_count: return False
+        if self.actions != other.actions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("duration_sec = ");
+                q.text("%#x" % self.duration_sec)
+                q.text(","); q.breakable()
+                q.text("duration_nsec = ");
+                q.text("%#x" % self.duration_nsec)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("packet_count = ");
+                q.text("%#x" % self.packet_count)
+                q.text(","); q.breakable()
+                q.text("byte_count = ");
+                q.text("%#x" % self.byte_count)
+                q.text(","); q.breakable()
+                q.text("actions = ");
+                q.pp(self.actions)
+            q.breakable()
+        q.text('}')
+
+
+class match_v1(loxi.OFObject):
+
+    def __init__(self, wildcards=None, in_port=None, eth_src=None, eth_dst=None, vlan_vid=None, vlan_pcp=None, eth_type=None, ip_dscp=None, ip_proto=None, ipv4_src=None, ipv4_dst=None, tcp_src=None, tcp_dst=None):
+        if wildcards != None:
+            self.wildcards = wildcards
+        else:
+            self.wildcards = util.init_wc_bmap()
+        if in_port != None:
+            self.in_port = in_port
+        else:
+            self.in_port = 0
+        if eth_src != None:
+            self.eth_src = eth_src
+        else:
+            self.eth_src = [0,0,0,0,0,0]
+        if eth_dst != None:
+            self.eth_dst = eth_dst
+        else:
+            self.eth_dst = [0,0,0,0,0,0]
+        if vlan_vid != None:
+            self.vlan_vid = vlan_vid
+        else:
+            self.vlan_vid = 0
+        if vlan_pcp != None:
+            self.vlan_pcp = vlan_pcp
+        else:
+            self.vlan_pcp = 0
+        if eth_type != None:
+            self.eth_type = eth_type
+        else:
+            self.eth_type = 0
+        if ip_dscp != None:
+            self.ip_dscp = ip_dscp
+        else:
+            self.ip_dscp = 0
+        if ip_proto != None:
+            self.ip_proto = ip_proto
+        else:
+            self.ip_proto = 0
+        if ipv4_src != None:
+            self.ipv4_src = ipv4_src
+        else:
+            self.ipv4_src = 0
+        if ipv4_dst != None:
+            self.ipv4_dst = ipv4_dst
+        else:
+            self.ipv4_dst = 0
+        if tcp_src != None:
+            self.tcp_src = tcp_src
+        else:
+            self.tcp_src = 0
+        if tcp_dst != None:
+            self.tcp_dst = tcp_dst
+        else:
+            self.tcp_dst = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(util.pack_wc_bmap(self.wildcards))
+        packed.append(util.pack_port_no(self.in_port))
+        packed.append(struct.pack("!6B", *self.eth_src))
+        packed.append(struct.pack("!6B", *self.eth_dst))
+        packed.append(struct.pack("!H", self.vlan_vid))
+        packed.append(struct.pack("!B", self.vlan_pcp))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!H", self.eth_type))
+        packed.append(struct.pack("!B", self.ip_dscp))
+        packed.append(struct.pack("!B", self.ip_proto))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!L", self.ipv4_src))
+        packed.append(struct.pack("!L", self.ipv4_dst))
+        packed.append(struct.pack("!H", self.tcp_src))
+        packed.append(struct.pack("!H", self.tcp_dst))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = match_v1()
+        obj.wildcards = util.unpack_wc_bmap(reader)
+        obj.in_port = util.unpack_port_no(reader)
+        obj.eth_src = list(reader.read('!6B'))
+        obj.eth_dst = list(reader.read('!6B'))
+        obj.vlan_vid = reader.read("!H")[0]
+        obj.vlan_pcp = reader.read("!B")[0]
+        reader.skip(1)
+        obj.eth_type = reader.read("!H")[0]
+        obj.ip_dscp = reader.read("!B")[0]
+        obj.ip_proto = reader.read("!B")[0]
+        reader.skip(2)
+        obj.ipv4_src = reader.read("!L")[0]
+        obj.ipv4_dst = reader.read("!L")[0]
+        obj.tcp_src = reader.read("!H")[0]
+        obj.tcp_dst = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.wildcards != other.wildcards: return False
+        if self.in_port != other.in_port: return False
+        if self.eth_src != other.eth_src: return False
+        if self.eth_dst != other.eth_dst: return False
+        if self.vlan_vid != other.vlan_vid: return False
+        if self.vlan_pcp != other.vlan_pcp: return False
+        if self.eth_type != other.eth_type: return False
+        if self.ip_dscp != other.ip_dscp: return False
+        if self.ip_proto != other.ip_proto: return False
+        if self.ipv4_src != other.ipv4_src: return False
+        if self.ipv4_dst != other.ipv4_dst: return False
+        if self.tcp_src != other.tcp_src: return False
+        if self.tcp_dst != other.tcp_dst: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("match_v1 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("wildcards = ");
+                q.text(util.pretty_wildcards(self.wildcards))
+                q.text(","); q.breakable()
+                q.text("in_port = ");
+                q.text(util.pretty_port(self.in_port))
+                q.text(","); q.breakable()
+                q.text("eth_src = ");
+                q.text(util.pretty_mac(self.eth_src))
+                q.text(","); q.breakable()
+                q.text("eth_dst = ");
+                q.text(util.pretty_mac(self.eth_dst))
+                q.text(","); q.breakable()
+                q.text("vlan_vid = ");
+                q.text("%#x" % self.vlan_vid)
+                q.text(","); q.breakable()
+                q.text("vlan_pcp = ");
+                q.text("%#x" % self.vlan_pcp)
+                q.text(","); q.breakable()
+                q.text("eth_type = ");
+                q.text("%#x" % self.eth_type)
+                q.text(","); q.breakable()
+                q.text("ip_dscp = ");
+                q.text("%#x" % self.ip_dscp)
+                q.text(","); q.breakable()
+                q.text("ip_proto = ");
+                q.text("%#x" % self.ip_proto)
+                q.text(","); q.breakable()
+                q.text("ipv4_src = ");
+                q.text(util.pretty_ipv4(self.ipv4_src))
+                q.text(","); q.breakable()
+                q.text("ipv4_dst = ");
+                q.text(util.pretty_ipv4(self.ipv4_dst))
+                q.text(","); q.breakable()
+                q.text("tcp_src = ");
+                q.text("%#x" % self.tcp_src)
+                q.text(","); q.breakable()
+                q.text("tcp_dst = ");
+                q.text("%#x" % self.tcp_dst)
+            q.breakable()
+        q.text('}')
+
+
+class packet_queue(loxi.OFObject):
+
+    def __init__(self, queue_id=None, properties=None):
+        if queue_id != None:
+            self.queue_id = queue_id
+        else:
+            self.queue_id = 0
+        if properties != None:
+            self.properties = properties
+        else:
+            self.properties = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.queue_id))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 2)
+        packed.append(loxi.generic_util.pack_list(self.properties))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = packet_queue()
+        obj.queue_id = reader.read("!L")[0]
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 6)
+        reader.skip(2)
+        obj.properties = loxi.generic_util.unpack_list(reader, ofp.common.queue_prop.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.queue_id != other.queue_id: return False
+        if self.properties != other.properties: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("packet_queue {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("queue_id = ");
+                q.text("%#x" % self.queue_id)
+                q.text(","); q.breakable()
+                q.text("properties = ");
+                q.pp(self.properties)
+            q.breakable()
+        q.text('}')
+
+
+class port_desc(loxi.OFObject):
+
+    def __init__(self, port_no=None, hw_addr=None, name=None, config=None, state=None, curr=None, advertised=None, supported=None, peer=None):
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if hw_addr != None:
+            self.hw_addr = hw_addr
+        else:
+            self.hw_addr = [0,0,0,0,0,0]
+        if name != None:
+            self.name = name
+        else:
+            self.name = ""
+        if config != None:
+            self.config = config
+        else:
+            self.config = 0
+        if state != None:
+            self.state = state
+        else:
+            self.state = 0
+        if curr != None:
+            self.curr = curr
+        else:
+            self.curr = 0
+        if advertised != None:
+            self.advertised = advertised
+        else:
+            self.advertised = 0
+        if supported != None:
+            self.supported = supported
+        else:
+            self.supported = 0
+        if peer != None:
+            self.peer = peer
+        else:
+            self.peer = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!6B", *self.hw_addr))
+        packed.append(struct.pack("!16s", self.name))
+        packed.append(struct.pack("!L", self.config))
+        packed.append(struct.pack("!L", self.state))
+        packed.append(struct.pack("!L", self.curr))
+        packed.append(struct.pack("!L", self.advertised))
+        packed.append(struct.pack("!L", self.supported))
+        packed.append(struct.pack("!L", self.peer))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_desc()
+        obj.port_no = util.unpack_port_no(reader)
+        obj.hw_addr = list(reader.read('!6B'))
+        obj.name = reader.read("!16s")[0].rstrip("\x00")
+        obj.config = reader.read("!L")[0]
+        obj.state = reader.read("!L")[0]
+        obj.curr = reader.read("!L")[0]
+        obj.advertised = reader.read("!L")[0]
+        obj.supported = reader.read("!L")[0]
+        obj.peer = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.port_no != other.port_no: return False
+        if self.hw_addr != other.hw_addr: return False
+        if self.name != other.name: return False
+        if self.config != other.config: return False
+        if self.state != other.state: return False
+        if self.curr != other.curr: return False
+        if self.advertised != other.advertised: return False
+        if self.supported != other.supported: return False
+        if self.peer != other.peer: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_desc {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("hw_addr = ");
+                q.text(util.pretty_mac(self.hw_addr))
+                q.text(","); q.breakable()
+                q.text("name = ");
+                q.pp(self.name)
+                q.text(","); q.breakable()
+                q.text("config = ");
+                q.text("%#x" % self.config)
+                q.text(","); q.breakable()
+                q.text("state = ");
+                q.text("%#x" % self.state)
+                q.text(","); q.breakable()
+                q.text("curr = ");
+                q.text("%#x" % self.curr)
+                q.text(","); q.breakable()
+                q.text("advertised = ");
+                q.text("%#x" % self.advertised)
+                q.text(","); q.breakable()
+                q.text("supported = ");
+                q.text("%#x" % self.supported)
+                q.text(","); q.breakable()
+                q.text("peer = ");
+                q.text("%#x" % self.peer)
+            q.breakable()
+        q.text('}')
+
+
+class port_stats_entry(loxi.OFObject):
+
+    def __init__(self, port_no=None, rx_packets=None, tx_packets=None, rx_bytes=None, tx_bytes=None, rx_dropped=None, tx_dropped=None, rx_errors=None, tx_errors=None, rx_frame_err=None, rx_over_err=None, rx_crc_err=None, collisions=None):
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if rx_packets != None:
+            self.rx_packets = rx_packets
+        else:
+            self.rx_packets = 0
+        if tx_packets != None:
+            self.tx_packets = tx_packets
+        else:
+            self.tx_packets = 0
+        if rx_bytes != None:
+            self.rx_bytes = rx_bytes
+        else:
+            self.rx_bytes = 0
+        if tx_bytes != None:
+            self.tx_bytes = tx_bytes
+        else:
+            self.tx_bytes = 0
+        if rx_dropped != None:
+            self.rx_dropped = rx_dropped
+        else:
+            self.rx_dropped = 0
+        if tx_dropped != None:
+            self.tx_dropped = tx_dropped
+        else:
+            self.tx_dropped = 0
+        if rx_errors != None:
+            self.rx_errors = rx_errors
+        else:
+            self.rx_errors = 0
+        if tx_errors != None:
+            self.tx_errors = tx_errors
+        else:
+            self.tx_errors = 0
+        if rx_frame_err != None:
+            self.rx_frame_err = rx_frame_err
+        else:
+            self.rx_frame_err = 0
+        if rx_over_err != None:
+            self.rx_over_err = rx_over_err
+        else:
+            self.rx_over_err = 0
+        if rx_crc_err != None:
+            self.rx_crc_err = rx_crc_err
+        else:
+            self.rx_crc_err = 0
+        if collisions != None:
+            self.collisions = collisions
+        else:
+            self.collisions = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append('\x00' * 6)
+        packed.append(struct.pack("!Q", self.rx_packets))
+        packed.append(struct.pack("!Q", self.tx_packets))
+        packed.append(struct.pack("!Q", self.rx_bytes))
+        packed.append(struct.pack("!Q", self.tx_bytes))
+        packed.append(struct.pack("!Q", self.rx_dropped))
+        packed.append(struct.pack("!Q", self.tx_dropped))
+        packed.append(struct.pack("!Q", self.rx_errors))
+        packed.append(struct.pack("!Q", self.tx_errors))
+        packed.append(struct.pack("!Q", self.rx_frame_err))
+        packed.append(struct.pack("!Q", self.rx_over_err))
+        packed.append(struct.pack("!Q", self.rx_crc_err))
+        packed.append(struct.pack("!Q", self.collisions))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_stats_entry()
+        obj.port_no = util.unpack_port_no(reader)
+        reader.skip(6)
+        obj.rx_packets = reader.read("!Q")[0]
+        obj.tx_packets = reader.read("!Q")[0]
+        obj.rx_bytes = reader.read("!Q")[0]
+        obj.tx_bytes = reader.read("!Q")[0]
+        obj.rx_dropped = reader.read("!Q")[0]
+        obj.tx_dropped = reader.read("!Q")[0]
+        obj.rx_errors = reader.read("!Q")[0]
+        obj.tx_errors = reader.read("!Q")[0]
+        obj.rx_frame_err = reader.read("!Q")[0]
+        obj.rx_over_err = reader.read("!Q")[0]
+        obj.rx_crc_err = reader.read("!Q")[0]
+        obj.collisions = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.port_no != other.port_no: return False
+        if self.rx_packets != other.rx_packets: return False
+        if self.tx_packets != other.tx_packets: return False
+        if self.rx_bytes != other.rx_bytes: return False
+        if self.tx_bytes != other.tx_bytes: return False
+        if self.rx_dropped != other.rx_dropped: return False
+        if self.tx_dropped != other.tx_dropped: return False
+        if self.rx_errors != other.rx_errors: return False
+        if self.tx_errors != other.tx_errors: return False
+        if self.rx_frame_err != other.rx_frame_err: return False
+        if self.rx_over_err != other.rx_over_err: return False
+        if self.rx_crc_err != other.rx_crc_err: return False
+        if self.collisions != other.collisions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("rx_packets = ");
+                q.text("%#x" % self.rx_packets)
+                q.text(","); q.breakable()
+                q.text("tx_packets = ");
+                q.text("%#x" % self.tx_packets)
+                q.text(","); q.breakable()
+                q.text("rx_bytes = ");
+                q.text("%#x" % self.rx_bytes)
+                q.text(","); q.breakable()
+                q.text("tx_bytes = ");
+                q.text("%#x" % self.tx_bytes)
+                q.text(","); q.breakable()
+                q.text("rx_dropped = ");
+                q.text("%#x" % self.rx_dropped)
+                q.text(","); q.breakable()
+                q.text("tx_dropped = ");
+                q.text("%#x" % self.tx_dropped)
+                q.text(","); q.breakable()
+                q.text("rx_errors = ");
+                q.text("%#x" % self.rx_errors)
+                q.text(","); q.breakable()
+                q.text("tx_errors = ");
+                q.text("%#x" % self.tx_errors)
+                q.text(","); q.breakable()
+                q.text("rx_frame_err = ");
+                q.text("%#x" % self.rx_frame_err)
+                q.text(","); q.breakable()
+                q.text("rx_over_err = ");
+                q.text("%#x" % self.rx_over_err)
+                q.text(","); q.breakable()
+                q.text("rx_crc_err = ");
+                q.text("%#x" % self.rx_crc_err)
+                q.text(","); q.breakable()
+                q.text("collisions = ");
+                q.text("%#x" % self.collisions)
+            q.breakable()
+        q.text('}')
+
+
+class queue_prop(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = queue_prop.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = queue_prop()
+        obj.type = reader.read("!H")[0]
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_prop {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class queue_prop_min_rate(queue_prop):
+    type = 1
+
+    def __init__(self, rate=None):
+        if rate != None:
+            self.rate = rate
+        else:
+            self.rate = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!H", self.rate))
+        packed.append('\x00' * 6)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_prop_min_rate()
+        _type = reader.read("!H")[0]
+        assert(_type == 1)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        obj.rate = reader.read("!H")[0]
+        reader.skip(6)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.rate != other.rate: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_prop_min_rate {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("rate = ");
+                q.text("%#x" % self.rate)
+            q.breakable()
+        q.text('}')
+
+queue_prop.subtypes[1] = queue_prop_min_rate
+
+class queue_stats_entry(loxi.OFObject):
+
+    def __init__(self, port_no=None, queue_id=None, tx_bytes=None, tx_packets=None, tx_errors=None):
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if queue_id != None:
+            self.queue_id = queue_id
+        else:
+            self.queue_id = 0
+        if tx_bytes != None:
+            self.tx_bytes = tx_bytes
+        else:
+            self.tx_bytes = 0
+        if tx_packets != None:
+            self.tx_packets = tx_packets
+        else:
+            self.tx_packets = 0
+        if tx_errors != None:
+            self.tx_errors = tx_errors
+        else:
+            self.tx_errors = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!L", self.queue_id))
+        packed.append(struct.pack("!Q", self.tx_bytes))
+        packed.append(struct.pack("!Q", self.tx_packets))
+        packed.append(struct.pack("!Q", self.tx_errors))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_stats_entry()
+        obj.port_no = util.unpack_port_no(reader)
+        reader.skip(2)
+        obj.queue_id = reader.read("!L")[0]
+        obj.tx_bytes = reader.read("!Q")[0]
+        obj.tx_packets = reader.read("!Q")[0]
+        obj.tx_errors = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.port_no != other.port_no: return False
+        if self.queue_id != other.queue_id: return False
+        if self.tx_bytes != other.tx_bytes: return False
+        if self.tx_packets != other.tx_packets: return False
+        if self.tx_errors != other.tx_errors: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("queue_id = ");
+                q.text("%#x" % self.queue_id)
+                q.text(","); q.breakable()
+                q.text("tx_bytes = ");
+                q.text("%#x" % self.tx_bytes)
+                q.text(","); q.breakable()
+                q.text("tx_packets = ");
+                q.text("%#x" % self.tx_packets)
+                q.text(","); q.breakable()
+                q.text("tx_errors = ");
+                q.text("%#x" % self.tx_errors)
+            q.breakable()
+        q.text('}')
+
+
+class table_stats_entry(loxi.OFObject):
+
+    def __init__(self, table_id=None, name=None, wildcards=None, max_entries=None, active_count=None, lookup_count=None, matched_count=None):
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if name != None:
+            self.name = name
+        else:
+            self.name = ""
+        if wildcards != None:
+            self.wildcards = wildcards
+        else:
+            self.wildcards = util.init_wc_bmap()
+        if max_entries != None:
+            self.max_entries = max_entries
+        else:
+            self.max_entries = 0
+        if active_count != None:
+            self.active_count = active_count
+        else:
+            self.active_count = 0
+        if lookup_count != None:
+            self.lookup_count = lookup_count
+        else:
+            self.lookup_count = 0
+        if matched_count != None:
+            self.matched_count = matched_count
+        else:
+            self.matched_count = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append('\x00' * 3)
+        packed.append(struct.pack("!32s", self.name))
+        packed.append(util.pack_wc_bmap(self.wildcards))
+        packed.append(struct.pack("!L", self.max_entries))
+        packed.append(struct.pack("!L", self.active_count))
+        packed.append(struct.pack("!Q", self.lookup_count))
+        packed.append(struct.pack("!Q", self.matched_count))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_stats_entry()
+        obj.table_id = reader.read("!B")[0]
+        reader.skip(3)
+        obj.name = reader.read("!32s")[0].rstrip("\x00")
+        obj.wildcards = util.unpack_wc_bmap(reader)
+        obj.max_entries = reader.read("!L")[0]
+        obj.active_count = reader.read("!L")[0]
+        obj.lookup_count = reader.read("!Q")[0]
+        obj.matched_count = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.table_id != other.table_id: return False
+        if self.name != other.name: return False
+        if self.wildcards != other.wildcards: return False
+        if self.max_entries != other.max_entries: return False
+        if self.active_count != other.active_count: return False
+        if self.lookup_count != other.lookup_count: return False
+        if self.matched_count != other.matched_count: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("name = ");
+                q.pp(self.name)
+                q.text(","); q.breakable()
+                q.text("wildcards = ");
+                q.text(util.pretty_wildcards(self.wildcards))
+                q.text(","); q.breakable()
+                q.text("max_entries = ");
+                q.text("%#x" % self.max_entries)
+                q.text(","); q.breakable()
+                q.text("active_count = ");
+                q.text("%#x" % self.active_count)
+                q.text(","); q.breakable()
+                q.text("lookup_count = ");
+                q.text("%#x" % self.lookup_count)
+                q.text(","); q.breakable()
+                q.text("matched_count = ");
+                q.text("%#x" % self.matched_count)
+            q.breakable()
+        q.text('}')
+
+
+
+match = match_v1
diff --git a/Fabric/Utilities/src/python/loxi/of10/const.py b/Fabric/Utilities/src/python/loxi/of10/const.py
new file mode 100644
index 0000000..27d4c76
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of10/const.py
@@ -0,0 +1,538 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template const.py
+# Do not modify
+
+OFP_VERSION = 1
+
+# Identifiers from group macro_definitions
+OFP_MAX_TABLE_NAME_LEN = 32
+OFP_MAX_PORT_NAME_LEN = 16
+OFP_TCP_PORT = 6653
+OFP_SSL_PORT = 6653
+OFP_ETH_ALEN = 6
+OFP_DEFAULT_MISS_SEND_LEN = 128
+OFP_VLAN_NONE = 65535
+OFPFW_ICMP_TYPE = 64
+OFPFW_ICMP_CODE = 128
+OFP_DL_TYPE_ETH2_CUTOFF = 1536
+OFP_DL_TYPE_NOT_ETH_TYPE = 1535
+OFP_FLOW_PERMANENT = 0
+OFP_DEFAULT_PRIORITY = 32768
+DESC_STR_LEN = 256
+SERIAL_NUM_LEN = 32
+OFPQ_ALL = 4294967295
+OFPQ_MIN_RATE_UNCFG = 65535
+
+# Identifiers from group of_bsn_pdu_slot_num
+BSN_PDU_SLOT_NUM_ANY = 255
+
+of_bsn_pdu_slot_num_map = {
+    255: 'BSN_PDU_SLOT_NUM_ANY',
+}
+
+# Identifiers from group ofp_action_type
+OFPAT_OUTPUT = 0
+OFPAT_SET_VLAN_VID = 1
+OFPAT_SET_VLAN_PCP = 2
+OFPAT_STRIP_VLAN = 3
+OFPAT_SET_DL_SRC = 4
+OFPAT_SET_DL_DST = 5
+OFPAT_SET_NW_SRC = 6
+OFPAT_SET_NW_DST = 7
+OFPAT_SET_NW_TOS = 8
+OFPAT_SET_TP_SRC = 9
+OFPAT_SET_TP_DST = 10
+OFPAT_ENQUEUE = 11
+OFPAT_EXPERIMENTER = 65535
+
+ofp_action_type_map = {
+    0: 'OFPAT_OUTPUT',
+    1: 'OFPAT_SET_VLAN_VID',
+    2: 'OFPAT_SET_VLAN_PCP',
+    3: 'OFPAT_STRIP_VLAN',
+    4: 'OFPAT_SET_DL_SRC',
+    5: 'OFPAT_SET_DL_DST',
+    6: 'OFPAT_SET_NW_SRC',
+    7: 'OFPAT_SET_NW_DST',
+    8: 'OFPAT_SET_NW_TOS',
+    9: 'OFPAT_SET_TP_SRC',
+    10: 'OFPAT_SET_TP_DST',
+    11: 'OFPAT_ENQUEUE',
+    65535: 'OFPAT_EXPERIMENTER',
+}
+
+# Identifiers from group ofp_bad_action_code
+OFPBAC_BAD_TYPE = 0
+OFPBAC_BAD_LEN = 1
+OFPBAC_BAD_EXPERIMENTER = 2
+OFPBAC_BAD_EXPERIMENTER_TYPE = 3
+OFPBAC_BAD_OUT_PORT = 4
+OFPBAC_BAD_ARGUMENT = 5
+OFPBAC_EPERM = 6
+OFPBAC_TOO_MANY = 7
+OFPBAC_BAD_QUEUE = 8
+
+ofp_bad_action_code_map = {
+    0: 'OFPBAC_BAD_TYPE',
+    1: 'OFPBAC_BAD_LEN',
+    2: 'OFPBAC_BAD_EXPERIMENTER',
+    3: 'OFPBAC_BAD_EXPERIMENTER_TYPE',
+    4: 'OFPBAC_BAD_OUT_PORT',
+    5: 'OFPBAC_BAD_ARGUMENT',
+    6: 'OFPBAC_EPERM',
+    7: 'OFPBAC_TOO_MANY',
+    8: 'OFPBAC_BAD_QUEUE',
+}
+
+# Identifiers from group ofp_bad_request_code
+OFPBRC_BAD_VERSION = 0
+OFPBRC_BAD_TYPE = 1
+OFPBRC_BAD_STAT = 2
+OFPBRC_BAD_EXPERIMENTER = 3
+OFPBRC_BAD_SUBTYPE = 4
+OFPBRC_EPERM = 5
+OFPBRC_BAD_LEN = 6
+OFPBRC_BUFFER_EMPTY = 7
+OFPBRC_BUFFER_UNKNOWN = 8
+
+ofp_bad_request_code_map = {
+    0: 'OFPBRC_BAD_VERSION',
+    1: 'OFPBRC_BAD_TYPE',
+    2: 'OFPBRC_BAD_STAT',
+    3: 'OFPBRC_BAD_EXPERIMENTER',
+    4: 'OFPBRC_BAD_SUBTYPE',
+    5: 'OFPBRC_EPERM',
+    6: 'OFPBRC_BAD_LEN',
+    7: 'OFPBRC_BUFFER_EMPTY',
+    8: 'OFPBRC_BUFFER_UNKNOWN',
+}
+
+# Identifiers from group ofp_bsn_vport_l2gre_flags
+OF_BSN_VPORT_L2GRE_LOCAL_MAC_IS_VALID = 1
+OF_BSN_VPORT_L2GRE_DSCP_ASSIGN = 2
+OF_BSN_VPORT_L2GRE_DSCP_COPY = 4
+OF_BSN_VPORT_L2GRE_LOOPBACK_IS_VALID = 8
+OF_BSN_VPORT_L2GRE_RATE_LIMIT_IS_VALID = 16
+
+ofp_bsn_vport_l2gre_flags_map = {
+    1: 'OF_BSN_VPORT_L2GRE_LOCAL_MAC_IS_VALID',
+    2: 'OF_BSN_VPORT_L2GRE_DSCP_ASSIGN',
+    4: 'OF_BSN_VPORT_L2GRE_DSCP_COPY',
+    8: 'OF_BSN_VPORT_L2GRE_LOOPBACK_IS_VALID',
+    16: 'OF_BSN_VPORT_L2GRE_RATE_LIMIT_IS_VALID',
+}
+
+# Identifiers from group ofp_bsn_vport_q_in_q_untagged
+OF_BSN_VPORT_Q_IN_Q_UNTAGGED = 65535
+
+ofp_bsn_vport_q_in_q_untagged_map = {
+    65535: 'OF_BSN_VPORT_Q_IN_Q_UNTAGGED',
+}
+
+# Identifiers from group ofp_bsn_vport_status
+OF_BSN_VPORT_STATUS_OK = 0
+OF_BSN_VPORT_STATUS_FAILED = 1
+
+ofp_bsn_vport_status_map = {
+    0: 'OF_BSN_VPORT_STATUS_OK',
+    1: 'OF_BSN_VPORT_STATUS_FAILED',
+}
+
+# Identifiers from group ofp_capabilities
+OFPC_FLOW_STATS = 1
+OFPC_TABLE_STATS = 2
+OFPC_PORT_STATS = 4
+OFPC_STP = 8
+OFPC_RESERVED = 16
+OFPC_IP_REASM = 32
+OFPC_QUEUE_STATS = 64
+OFPC_ARP_MATCH_IP = 128
+
+ofp_capabilities_map = {
+    1: 'OFPC_FLOW_STATS',
+    2: 'OFPC_TABLE_STATS',
+    4: 'OFPC_PORT_STATS',
+    8: 'OFPC_STP',
+    16: 'OFPC_RESERVED',
+    32: 'OFPC_IP_REASM',
+    64: 'OFPC_QUEUE_STATS',
+    128: 'OFPC_ARP_MATCH_IP',
+}
+
+# Identifiers from group ofp_config_flags
+OFPC_FRAG_NORMAL = 0
+OFPC_FRAG_DROP = 1
+OFPC_FRAG_REASM = 2
+OFPC_FRAG_MASK = 3
+
+ofp_config_flags_map = {
+    0: 'OFPC_FRAG_NORMAL',
+    1: 'OFPC_FRAG_DROP',
+    2: 'OFPC_FRAG_REASM',
+    3: 'OFPC_FRAG_MASK',
+}
+
+# Identifiers from group ofp_error_type
+OFPET_HELLO_FAILED = 0
+OFPET_BAD_REQUEST = 1
+OFPET_BAD_ACTION = 2
+OFPET_FLOW_MOD_FAILED = 3
+OFPET_PORT_MOD_FAILED = 4
+OFPET_QUEUE_OP_FAILED = 5
+
+ofp_error_type_map = {
+    0: 'OFPET_HELLO_FAILED',
+    1: 'OFPET_BAD_REQUEST',
+    2: 'OFPET_BAD_ACTION',
+    3: 'OFPET_FLOW_MOD_FAILED',
+    4: 'OFPET_PORT_MOD_FAILED',
+    5: 'OFPET_QUEUE_OP_FAILED',
+}
+
+# Identifiers from group ofp_flow_mod_command
+OFPFC_ADD = 0
+OFPFC_MODIFY = 1
+OFPFC_MODIFY_STRICT = 2
+OFPFC_DELETE = 3
+OFPFC_DELETE_STRICT = 4
+
+ofp_flow_mod_command_map = {
+    0: 'OFPFC_ADD',
+    1: 'OFPFC_MODIFY',
+    2: 'OFPFC_MODIFY_STRICT',
+    3: 'OFPFC_DELETE',
+    4: 'OFPFC_DELETE_STRICT',
+}
+
+# Identifiers from group ofp_flow_mod_failed_code
+OFPFMFC_ALL_TABLES_FULL = 0
+OFPFMFC_OVERLAP = 1
+OFPFMFC_EPERM = 2
+OFPFMFC_BAD_EMERG_TIMEOUT = 3
+OFPFMFC_BAD_COMMAND = 4
+OFPFMFC_UNSUPPORTED = 5
+
+ofp_flow_mod_failed_code_map = {
+    0: 'OFPFMFC_ALL_TABLES_FULL',
+    1: 'OFPFMFC_OVERLAP',
+    2: 'OFPFMFC_EPERM',
+    3: 'OFPFMFC_BAD_EMERG_TIMEOUT',
+    4: 'OFPFMFC_BAD_COMMAND',
+    5: 'OFPFMFC_UNSUPPORTED',
+}
+
+# Identifiers from group ofp_flow_mod_flags
+OFPFF_SEND_FLOW_REM = 1
+OFPFF_CHECK_OVERLAP = 2
+OFPFF_EMERG = 4
+
+ofp_flow_mod_flags_map = {
+    1: 'OFPFF_SEND_FLOW_REM',
+    2: 'OFPFF_CHECK_OVERLAP',
+    4: 'OFPFF_EMERG',
+}
+
+# Identifiers from group ofp_flow_removed_reason
+OFPRR_IDLE_TIMEOUT = 0
+OFPRR_HARD_TIMEOUT = 1
+OFPRR_DELETE = 2
+
+ofp_flow_removed_reason_map = {
+    0: 'OFPRR_IDLE_TIMEOUT',
+    1: 'OFPRR_HARD_TIMEOUT',
+    2: 'OFPRR_DELETE',
+}
+
+# Identifiers from group ofp_flow_wildcards
+OFPFW_IN_PORT = 1
+OFPFW_DL_VLAN = 2
+OFPFW_DL_SRC = 4
+OFPFW_NW_DST_BITS = 6
+OFPFW_NW_SRC_BITS = 6
+OFPFW_NW_SRC_SHIFT = 8
+OFPFW_DL_DST = 8
+OFPFW_NW_DST_SHIFT = 14
+OFPFW_DL_TYPE = 16
+OFPFW_NW_PROTO = 32
+OFPFW_TP_SRC = 64
+OFPFW_TP_DST = 128
+OFPFW_NW_SRC_ALL = 8192
+OFPFW_NW_SRC_MASK = 16128
+OFPFW_NW_DST_ALL = 524288
+OFPFW_NW_DST_MASK = 1032192
+OFPFW_DL_VLAN_PCP = 1048576
+OFPFW_NW_TOS = 2097152
+OFPFW_ALL = 4194303
+
+ofp_flow_wildcards_map = {
+    1: 'OFPFW_IN_PORT',
+    2: 'OFPFW_DL_VLAN',
+    4: 'OFPFW_DL_SRC',
+    8: 'OFPFW_DL_DST',
+    16: 'OFPFW_DL_TYPE',
+    32: 'OFPFW_NW_PROTO',
+    64: 'OFPFW_TP_SRC',
+    128: 'OFPFW_TP_DST',
+    1048576: 'OFPFW_DL_VLAN_PCP',
+    2097152: 'OFPFW_NW_TOS',
+}
+
+# Identifiers from group ofp_hello_failed_code
+OFPHFC_INCOMPATIBLE = 0
+OFPHFC_EPERM = 1
+
+ofp_hello_failed_code_map = {
+    0: 'OFPHFC_INCOMPATIBLE',
+    1: 'OFPHFC_EPERM',
+}
+
+# Identifiers from group ofp_nicira_controller_role
+NX_ROLE_OTHER = 0
+NX_ROLE_MASTER = 1
+NX_ROLE_SLAVE = 2
+
+ofp_nicira_controller_role_map = {
+    0: 'NX_ROLE_OTHER',
+    1: 'NX_ROLE_MASTER',
+    2: 'NX_ROLE_SLAVE',
+}
+
+# Identifiers from group ofp_packet_in_reason
+OFPR_NO_MATCH = 0
+OFPR_ACTION = 1
+
+ofp_packet_in_reason_map = {
+    0: 'OFPR_NO_MATCH',
+    1: 'OFPR_ACTION',
+}
+
+# Identifiers from group ofp_port
+OFPP_MAX = 0xff00
+OFPP_IN_PORT = 0xfff8
+OFPP_TABLE = 0xfff9
+OFPP_NORMAL = 0xfffa
+OFPP_FLOOD = 0xfffb
+OFPP_ALL = 0xfffc
+OFPP_CONTROLLER = 0xfffd
+OFPP_LOCAL = 0xfffe
+OFPP_NONE = 0xffff
+
+ofp_port_map = {
+    0xff00: 'OFPP_MAX',
+    0xfff8: 'OFPP_IN_PORT',
+    0xfff9: 'OFPP_TABLE',
+    0xfffa: 'OFPP_NORMAL',
+    0xfffb: 'OFPP_FLOOD',
+    0xfffc: 'OFPP_ALL',
+    0xfffd: 'OFPP_CONTROLLER',
+    0xfffe: 'OFPP_LOCAL',
+    0xffff: 'OFPP_NONE',
+}
+
+# Identifiers from group ofp_port_config
+OFPPC_PORT_DOWN = 1
+OFPPC_NO_STP = 2
+OFPPC_NO_RECV = 4
+OFPPC_NO_RECV_STP = 8
+OFPPC_NO_FLOOD = 16
+OFPPC_NO_FWD = 32
+OFPPC_NO_PACKET_IN = 64
+OFPPC_BSN_MIRROR_DEST = 2147483648
+
+ofp_port_config_map = {
+    1: 'OFPPC_PORT_DOWN',
+    2: 'OFPPC_NO_STP',
+    4: 'OFPPC_NO_RECV',
+    8: 'OFPPC_NO_RECV_STP',
+    16: 'OFPPC_NO_FLOOD',
+    32: 'OFPPC_NO_FWD',
+    64: 'OFPPC_NO_PACKET_IN',
+    2147483648: 'OFPPC_BSN_MIRROR_DEST',
+}
+
+# Identifiers from group ofp_port_features
+OFPPF_10MB_HD = 1
+OFPPF_10MB_FD = 2
+OFPPF_100MB_HD = 4
+OFPPF_100MB_FD = 8
+OFPPF_1GB_HD = 16
+OFPPF_1GB_FD = 32
+OFPPF_10GB_FD = 64
+OFPPF_COPPER = 128
+OFPPF_FIBER = 256
+OFPPF_AUTONEG = 512
+OFPPF_PAUSE = 1024
+OFPPF_PAUSE_ASYM = 2048
+
+ofp_port_features_map = {
+    1: 'OFPPF_10MB_HD',
+    2: 'OFPPF_10MB_FD',
+    4: 'OFPPF_100MB_HD',
+    8: 'OFPPF_100MB_FD',
+    16: 'OFPPF_1GB_HD',
+    32: 'OFPPF_1GB_FD',
+    64: 'OFPPF_10GB_FD',
+    128: 'OFPPF_COPPER',
+    256: 'OFPPF_FIBER',
+    512: 'OFPPF_AUTONEG',
+    1024: 'OFPPF_PAUSE',
+    2048: 'OFPPF_PAUSE_ASYM',
+}
+
+# Identifiers from group ofp_port_mod_failed_code
+OFPPMFC_BAD_PORT = 0
+OFPPMFC_BAD_HW_ADDR = 1
+
+ofp_port_mod_failed_code_map = {
+    0: 'OFPPMFC_BAD_PORT',
+    1: 'OFPPMFC_BAD_HW_ADDR',
+}
+
+# Identifiers from group ofp_port_reason
+OFPPR_ADD = 0
+OFPPR_DELETE = 1
+OFPPR_MODIFY = 2
+
+ofp_port_reason_map = {
+    0: 'OFPPR_ADD',
+    1: 'OFPPR_DELETE',
+    2: 'OFPPR_MODIFY',
+}
+
+# Identifiers from group ofp_port_state
+OFPPS_LINK_DOWN = 1
+OFPPS_STP_LISTEN = 0
+OFPPS_STP_LEARN = 256
+OFPPS_STP_FORWARD = 512
+OFPPS_STP_BLOCK = 768
+OFPPS_STP_MASK = 768
+
+ofp_port_state_map = {
+    1: 'OFPPS_LINK_DOWN',
+    0: 'OFPPS_STP_LISTEN',
+    256: 'OFPPS_STP_LEARN',
+    512: 'OFPPS_STP_FORWARD',
+    768: 'OFPPS_STP_BLOCK',
+    768: 'OFPPS_STP_MASK',
+}
+
+# Identifiers from group ofp_queue_op_failed_code
+OFPQOFC_BAD_PORT = 0
+OFPQOFC_BAD_QUEUE = 1
+OFPQOFC_EPERM = 2
+
+ofp_queue_op_failed_code_map = {
+    0: 'OFPQOFC_BAD_PORT',
+    1: 'OFPQOFC_BAD_QUEUE',
+    2: 'OFPQOFC_EPERM',
+}
+
+# Identifiers from group ofp_queue_properties
+OFPQT_NONE = 0
+OFPQT_MIN_RATE = 1
+
+ofp_queue_properties_map = {
+    0: 'OFPQT_NONE',
+    1: 'OFPQT_MIN_RATE',
+}
+
+# Identifiers from group ofp_stats_reply_flags
+OFPSF_REPLY_MORE = 1
+
+ofp_stats_reply_flags_map = {
+    1: 'OFPSF_REPLY_MORE',
+}
+
+# Identifiers from group ofp_stats_request_flags
+
+ofp_stats_request_flags_map = {
+}
+
+# Identifiers from group ofp_stats_type
+OFPST_DESC = 0
+OFPST_FLOW = 1
+OFPST_AGGREGATE = 2
+OFPST_TABLE = 3
+OFPST_PORT = 4
+OFPST_QUEUE = 5
+OFPST_EXPERIMENTER = 65535
+
+ofp_stats_type_map = {
+    0: 'OFPST_DESC',
+    1: 'OFPST_FLOW',
+    2: 'OFPST_AGGREGATE',
+    3: 'OFPST_TABLE',
+    4: 'OFPST_PORT',
+    5: 'OFPST_QUEUE',
+    65535: 'OFPST_EXPERIMENTER',
+}
+
+# Identifiers from group ofp_type
+OFPT_HELLO = 0
+OFPT_ERROR = 1
+OFPT_ECHO_REQUEST = 2
+OFPT_ECHO_REPLY = 3
+OFPT_EXPERIMENTER = 4
+OFPT_FEATURES_REQUEST = 5
+OFPT_FEATURES_REPLY = 6
+OFPT_GET_CONFIG_REQUEST = 7
+OFPT_GET_CONFIG_REPLY = 8
+OFPT_SET_CONFIG = 9
+OFPT_PACKET_IN = 10
+OFPT_FLOW_REMOVED = 11
+OFPT_PORT_STATUS = 12
+OFPT_PACKET_OUT = 13
+OFPT_FLOW_MOD = 14
+OFPT_PORT_MOD = 15
+OFPT_STATS_REQUEST = 16
+OFPT_STATS_REPLY = 17
+OFPT_BARRIER_REQUEST = 18
+OFPT_BARRIER_REPLY = 19
+OFPT_QUEUE_GET_CONFIG_REQUEST = 20
+OFPT_QUEUE_GET_CONFIG_REPLY = 21
+
+ofp_type_map = {
+    0: 'OFPT_HELLO',
+    1: 'OFPT_ERROR',
+    2: 'OFPT_ECHO_REQUEST',
+    3: 'OFPT_ECHO_REPLY',
+    4: 'OFPT_EXPERIMENTER',
+    5: 'OFPT_FEATURES_REQUEST',
+    6: 'OFPT_FEATURES_REPLY',
+    7: 'OFPT_GET_CONFIG_REQUEST',
+    8: 'OFPT_GET_CONFIG_REPLY',
+    9: 'OFPT_SET_CONFIG',
+    10: 'OFPT_PACKET_IN',
+    11: 'OFPT_FLOW_REMOVED',
+    12: 'OFPT_PORT_STATUS',
+    13: 'OFPT_PACKET_OUT',
+    14: 'OFPT_FLOW_MOD',
+    15: 'OFPT_PORT_MOD',
+    16: 'OFPT_STATS_REQUEST',
+    17: 'OFPT_STATS_REPLY',
+    18: 'OFPT_BARRIER_REQUEST',
+    19: 'OFPT_BARRIER_REPLY',
+    20: 'OFPT_QUEUE_GET_CONFIG_REQUEST',
+    21: 'OFPT_QUEUE_GET_CONFIG_REPLY',
+}
+
diff --git a/Fabric/Utilities/src/python/loxi/of10/message.py b/Fabric/Utilities/src/python/loxi/of10/message.py
new file mode 100644
index 0000000..5ffc5f3
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of10/message.py
@@ -0,0 +1,7553 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of10']
+
+class message(loxi.OFObject):
+    subtypes = {}
+
+    version = 1
+
+    def __init__(self, type=None, xid=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('B', 1)
+        subclass = message.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = message()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        obj.type = reader.read("!B")[0]
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("message {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+
+class stats_reply(message):
+    subtypes = {}
+
+    version = 1
+    type = 17
+
+    def __init__(self, xid=None, stats_type=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if stats_type != None:
+            self.stats_type = stats_type
+        else:
+            self.stats_type = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 8)
+        subclass = stats_reply.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 17)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.stats_type = reader.read("!H")[0]
+        obj.flags = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.stats_type != other.stats_type: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[17] = stats_reply
+
+class aggregate_stats_reply(stats_reply):
+    version = 1
+    type = 17
+    stats_type = 2
+
+    def __init__(self, xid=None, flags=None, packet_count=None, byte_count=None, flow_count=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if packet_count != None:
+            self.packet_count = packet_count
+        else:
+            self.packet_count = 0
+        if byte_count != None:
+            self.byte_count = byte_count
+        else:
+            self.byte_count = 0
+        if flow_count != None:
+            self.flow_count = flow_count
+        else:
+            self.flow_count = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(struct.pack("!Q", self.packet_count))
+        packed.append(struct.pack("!Q", self.byte_count))
+        packed.append(struct.pack("!L", self.flow_count))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = aggregate_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 17)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 2)
+        obj.flags = reader.read("!H")[0]
+        obj.packet_count = reader.read("!Q")[0]
+        obj.byte_count = reader.read("!Q")[0]
+        obj.flow_count = reader.read("!L")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.packet_count != other.packet_count: return False
+        if self.byte_count != other.byte_count: return False
+        if self.flow_count != other.flow_count: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("aggregate_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("packet_count = ");
+                q.text("%#x" % self.packet_count)
+                q.text(","); q.breakable()
+                q.text("byte_count = ");
+                q.text("%#x" % self.byte_count)
+                q.text(","); q.breakable()
+                q.text("flow_count = ");
+                q.text("%#x" % self.flow_count)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[2] = aggregate_stats_reply
+
+class stats_request(message):
+    subtypes = {}
+
+    version = 1
+    type = 16
+
+    def __init__(self, xid=None, stats_type=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if stats_type != None:
+            self.stats_type = stats_type
+        else:
+            self.stats_type = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 8)
+        subclass = stats_request.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 16)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.stats_type = reader.read("!H")[0]
+        obj.flags = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.stats_type != other.stats_type: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[16] = stats_request
+
+class aggregate_stats_request(stats_request):
+    version = 1
+    type = 16
+    stats_type = 2
+
+    def __init__(self, xid=None, flags=None, match=None, table_id=None, out_port=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(self.match.pack())
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append('\x00' * 1)
+        packed.append(util.pack_port_no(self.out_port))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = aggregate_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 16)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 2)
+        obj.flags = reader.read("!H")[0]
+        obj.match = ofp.match.unpack(reader)
+        obj.table_id = reader.read("!B")[0]
+        reader.skip(1)
+        obj.out_port = util.unpack_port_no(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.match != other.match: return False
+        if self.table_id != other.table_id: return False
+        if self.out_port != other.out_port: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("aggregate_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[2] = aggregate_stats_request
+
+class error_msg(message):
+    subtypes = {}
+
+    version = 1
+    type = 1
+
+    def __init__(self, xid=None, err_type=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if err_type != None:
+            self.err_type = err_type
+        else:
+            self.err_type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 8)
+        subclass = error_msg.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.err_type = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.err_type != other.err_type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+message.subtypes[1] = error_msg
+
+class bad_action_error_msg(error_msg):
+    version = 1
+    type = 1
+    err_type = 2
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bad_action_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 2)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bad_action_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[2] = bad_action_error_msg
+
+class bad_request_error_msg(error_msg):
+    version = 1
+    type = 1
+    err_type = 1
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bad_request_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 1)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bad_request_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[1] = bad_request_error_msg
+
+class barrier_reply(message):
+    version = 1
+    type = 19
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = barrier_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("barrier_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+message.subtypes[19] = barrier_reply
+
+class barrier_request(message):
+    version = 1
+    type = 18
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = barrier_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("barrier_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+message.subtypes[18] = barrier_request
+
+class experimenter(message):
+    subtypes = {}
+
+    version = 1
+    type = 4
+
+    def __init__(self, xid=None, experimenter=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 8)
+        subclass = experimenter.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = experimenter()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.experimenter = reader.read("!L")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.experimenter != other.experimenter: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[4] = experimenter
+
+class bsn_header(experimenter):
+    subtypes = {}
+
+    version = 1
+    type = 4
+    experimenter = 6035143
+
+    def __init__(self, xid=None, subtype=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 12)
+        subclass = bsn_header.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = bsn_header()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        obj.subtype = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_header {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+experimenter.subtypes[6035143] = bsn_header
+
+class bsn_bw_clear_data_reply(bsn_header):
+    version = 1
+    type = 4
+    experimenter = 6035143
+    subtype = 22
+
+    def __init__(self, xid=None, status=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.status))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_bw_clear_data_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 22)
+        obj.status = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.status != other.status: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_bw_clear_data_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[22] = bsn_bw_clear_data_reply
+
+class bsn_bw_clear_data_request(bsn_header):
+    version = 1
+    type = 4
+    experimenter = 6035143
+    subtype = 21
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_bw_clear_data_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 21)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_bw_clear_data_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[21] = bsn_bw_clear_data_request
+
+class bsn_bw_enable_get_reply(bsn_header):
+    version = 1
+    type = 4
+    experimenter = 6035143
+    subtype = 20
+
+    def __init__(self, xid=None, enabled=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if enabled != None:
+            self.enabled = enabled
+        else:
+            self.enabled = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.enabled))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_bw_enable_get_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 20)
+        obj.enabled = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.enabled != other.enabled: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_bw_enable_get_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("enabled = ");
+                q.text("%#x" % self.enabled)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[20] = bsn_bw_enable_get_reply
+
+class bsn_bw_enable_get_request(bsn_header):
+    version = 1
+    type = 4
+    experimenter = 6035143
+    subtype = 19
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_bw_enable_get_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 19)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_bw_enable_get_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[19] = bsn_bw_enable_get_request
+
+class bsn_bw_enable_set_reply(bsn_header):
+    version = 1
+    type = 4
+    experimenter = 6035143
+    subtype = 23
+
+    def __init__(self, xid=None, enable=None, status=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if enable != None:
+            self.enable = enable
+        else:
+            self.enable = 0
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.enable))
+        packed.append(struct.pack("!L", self.status))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_bw_enable_set_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 23)
+        obj.enable = reader.read("!L")[0]
+        obj.status = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.enable != other.enable: return False
+        if self.status != other.status: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_bw_enable_set_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("enable = ");
+                q.text("%#x" % self.enable)
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[23] = bsn_bw_enable_set_reply
+
+class bsn_bw_enable_set_request(bsn_header):
+    version = 1
+    type = 4
+    experimenter = 6035143
+    subtype = 18
+
+    def __init__(self, xid=None, enable=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if enable != None:
+            self.enable = enable
+        else:
+            self.enable = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.enable))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_bw_enable_set_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 18)
+        obj.enable = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.enable != other.enable: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_bw_enable_set_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("enable = ");
+                q.text("%#x" % self.enable)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[18] = bsn_bw_enable_set_request
+
+class bsn_get_interfaces_reply(bsn_header):
+    version = 1
+    type = 4
+    experimenter = 6035143
+    subtype = 10
+
+    def __init__(self, xid=None, interfaces=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if interfaces != None:
+            self.interfaces = interfaces
+        else:
+            self.interfaces = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.interfaces))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_get_interfaces_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 10)
+        obj.interfaces = loxi.generic_util.unpack_list(reader, ofp.common.bsn_interface.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.interfaces != other.interfaces: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_get_interfaces_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("interfaces = ");
+                q.pp(self.interfaces)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[10] = bsn_get_interfaces_reply
+
+class bsn_get_interfaces_request(bsn_header):
+    version = 1
+    type = 4
+    experimenter = 6035143
+    subtype = 9
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_get_interfaces_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 9)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_get_interfaces_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[9] = bsn_get_interfaces_request
+
+class bsn_get_ip_mask_reply(bsn_header):
+    version = 1
+    type = 4
+    experimenter = 6035143
+    subtype = 2
+
+    def __init__(self, xid=None, index=None, mask=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if index != None:
+            self.index = index
+        else:
+            self.index = 0
+        if mask != None:
+            self.mask = mask
+        else:
+            self.mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!B", self.index))
+        packed.append('\x00' * 3)
+        packed.append(struct.pack("!L", self.mask))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_get_ip_mask_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 2)
+        obj.index = reader.read("!B")[0]
+        reader.skip(3)
+        obj.mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.index != other.index: return False
+        if self.mask != other.mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_get_ip_mask_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("index = ");
+                q.text("%#x" % self.index)
+                q.text(","); q.breakable()
+                q.text("mask = ");
+                q.text("%#x" % self.mask)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[2] = bsn_get_ip_mask_reply
+
+class bsn_get_ip_mask_request(bsn_header):
+    version = 1
+    type = 4
+    experimenter = 6035143
+    subtype = 1
+
+    def __init__(self, xid=None, index=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if index != None:
+            self.index = index
+        else:
+            self.index = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!B", self.index))
+        packed.append('\x00' * 7)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_get_ip_mask_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 1)
+        obj.index = reader.read("!B")[0]
+        reader.skip(7)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.index != other.index: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_get_ip_mask_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("index = ");
+                q.text("%#x" % self.index)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[1] = bsn_get_ip_mask_request
+
+class bsn_get_l2_table_reply(bsn_header):
+    version = 1
+    type = 4
+    experimenter = 6035143
+    subtype = 14
+
+    def __init__(self, xid=None, l2_table_enable=None, l2_table_priority=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if l2_table_enable != None:
+            self.l2_table_enable = l2_table_enable
+        else:
+            self.l2_table_enable = 0
+        if l2_table_priority != None:
+            self.l2_table_priority = l2_table_priority
+        else:
+            self.l2_table_priority = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!B", self.l2_table_enable))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!H", self.l2_table_priority))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_get_l2_table_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 14)
+        obj.l2_table_enable = reader.read("!B")[0]
+        reader.skip(1)
+        obj.l2_table_priority = reader.read("!H")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.l2_table_enable != other.l2_table_enable: return False
+        if self.l2_table_priority != other.l2_table_priority: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_get_l2_table_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("l2_table_enable = ");
+                q.text("%#x" % self.l2_table_enable)
+                q.text(","); q.breakable()
+                q.text("l2_table_priority = ");
+                q.text("%#x" % self.l2_table_priority)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[14] = bsn_get_l2_table_reply
+
+class bsn_get_l2_table_request(bsn_header):
+    version = 1
+    type = 4
+    experimenter = 6035143
+    subtype = 13
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_get_l2_table_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 13)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_get_l2_table_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[13] = bsn_get_l2_table_request
+
+class bsn_get_mirroring_reply(bsn_header):
+    version = 1
+    type = 4
+    experimenter = 6035143
+    subtype = 5
+
+    def __init__(self, xid=None, report_mirror_ports=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if report_mirror_ports != None:
+            self.report_mirror_ports = report_mirror_ports
+        else:
+            self.report_mirror_ports = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!B", self.report_mirror_ports))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_get_mirroring_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 5)
+        obj.report_mirror_ports = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.report_mirror_ports != other.report_mirror_ports: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_get_mirroring_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("report_mirror_ports = ");
+                q.text("%#x" % self.report_mirror_ports)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[5] = bsn_get_mirroring_reply
+
+class bsn_get_mirroring_request(bsn_header):
+    version = 1
+    type = 4
+    experimenter = 6035143
+    subtype = 4
+
+    def __init__(self, xid=None, report_mirror_ports=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if report_mirror_ports != None:
+            self.report_mirror_ports = report_mirror_ports
+        else:
+            self.report_mirror_ports = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!B", self.report_mirror_ports))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_get_mirroring_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 4)
+        obj.report_mirror_ports = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.report_mirror_ports != other.report_mirror_ports: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_get_mirroring_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("report_mirror_ports = ");
+                q.text("%#x" % self.report_mirror_ports)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[4] = bsn_get_mirroring_request
+
+class bsn_hybrid_get_reply(bsn_header):
+    version = 1
+    type = 4
+    experimenter = 6035143
+    subtype = 28
+
+    def __init__(self, xid=None, hybrid_enable=None, hybrid_version=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if hybrid_enable != None:
+            self.hybrid_enable = hybrid_enable
+        else:
+            self.hybrid_enable = 0
+        if hybrid_version != None:
+            self.hybrid_version = hybrid_version
+        else:
+            self.hybrid_version = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!B", self.hybrid_enable))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!H", self.hybrid_version))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_hybrid_get_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 28)
+        obj.hybrid_enable = reader.read("!B")[0]
+        reader.skip(1)
+        obj.hybrid_version = reader.read("!H")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.hybrid_enable != other.hybrid_enable: return False
+        if self.hybrid_version != other.hybrid_version: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_hybrid_get_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("hybrid_enable = ");
+                q.text("%#x" % self.hybrid_enable)
+                q.text(","); q.breakable()
+                q.text("hybrid_version = ");
+                q.text("%#x" % self.hybrid_version)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[28] = bsn_hybrid_get_reply
+
+class bsn_hybrid_get_request(bsn_header):
+    version = 1
+    type = 4
+    experimenter = 6035143
+    subtype = 27
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_hybrid_get_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 27)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_hybrid_get_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[27] = bsn_hybrid_get_request
+
+class bsn_pdu_rx_reply(bsn_header):
+    version = 1
+    type = 4
+    experimenter = 6035143
+    subtype = 34
+
+    def __init__(self, xid=None, status=None, port_no=None, slot_num=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if slot_num != None:
+            self.slot_num = slot_num
+        else:
+            self.slot_num = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.status))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!B", self.slot_num))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_pdu_rx_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 34)
+        obj.status = reader.read("!L")[0]
+        obj.port_no = util.unpack_port_no(reader)
+        obj.slot_num = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.status != other.status: return False
+        if self.port_no != other.port_no: return False
+        if self.slot_num != other.slot_num: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_pdu_rx_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("slot_num = ");
+                q.text("%#x" % self.slot_num)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[34] = bsn_pdu_rx_reply
+
+class bsn_pdu_rx_request(bsn_header):
+    version = 1
+    type = 4
+    experimenter = 6035143
+    subtype = 33
+
+    def __init__(self, xid=None, timeout_ms=None, port_no=None, slot_num=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if timeout_ms != None:
+            self.timeout_ms = timeout_ms
+        else:
+            self.timeout_ms = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if slot_num != None:
+            self.slot_num = slot_num
+        else:
+            self.slot_num = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.timeout_ms))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!B", self.slot_num))
+        packed.append('\x00' * 3)
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_pdu_rx_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 33)
+        obj.timeout_ms = reader.read("!L")[0]
+        obj.port_no = util.unpack_port_no(reader)
+        obj.slot_num = reader.read("!B")[0]
+        reader.skip(3)
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.timeout_ms != other.timeout_ms: return False
+        if self.port_no != other.port_no: return False
+        if self.slot_num != other.slot_num: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_pdu_rx_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("timeout_ms = ");
+                q.text("%#x" % self.timeout_ms)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("slot_num = ");
+                q.text("%#x" % self.slot_num)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[33] = bsn_pdu_rx_request
+
+class bsn_pdu_rx_timeout(bsn_header):
+    version = 1
+    type = 4
+    experimenter = 6035143
+    subtype = 35
+
+    def __init__(self, xid=None, port_no=None, slot_num=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if slot_num != None:
+            self.slot_num = slot_num
+        else:
+            self.slot_num = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!B", self.slot_num))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_pdu_rx_timeout()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 35)
+        obj.port_no = util.unpack_port_no(reader)
+        obj.slot_num = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.port_no != other.port_no: return False
+        if self.slot_num != other.slot_num: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_pdu_rx_timeout {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("slot_num = ");
+                q.text("%#x" % self.slot_num)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[35] = bsn_pdu_rx_timeout
+
+class bsn_pdu_tx_reply(bsn_header):
+    version = 1
+    type = 4
+    experimenter = 6035143
+    subtype = 32
+
+    def __init__(self, xid=None, status=None, port_no=None, slot_num=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if slot_num != None:
+            self.slot_num = slot_num
+        else:
+            self.slot_num = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.status))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!B", self.slot_num))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_pdu_tx_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 32)
+        obj.status = reader.read("!L")[0]
+        obj.port_no = util.unpack_port_no(reader)
+        obj.slot_num = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.status != other.status: return False
+        if self.port_no != other.port_no: return False
+        if self.slot_num != other.slot_num: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_pdu_tx_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("slot_num = ");
+                q.text("%#x" % self.slot_num)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[32] = bsn_pdu_tx_reply
+
+class bsn_pdu_tx_request(bsn_header):
+    version = 1
+    type = 4
+    experimenter = 6035143
+    subtype = 31
+
+    def __init__(self, xid=None, tx_interval_ms=None, port_no=None, slot_num=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if tx_interval_ms != None:
+            self.tx_interval_ms = tx_interval_ms
+        else:
+            self.tx_interval_ms = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if slot_num != None:
+            self.slot_num = slot_num
+        else:
+            self.slot_num = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.tx_interval_ms))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!B", self.slot_num))
+        packed.append('\x00' * 3)
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_pdu_tx_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 31)
+        obj.tx_interval_ms = reader.read("!L")[0]
+        obj.port_no = util.unpack_port_no(reader)
+        obj.slot_num = reader.read("!B")[0]
+        reader.skip(3)
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.tx_interval_ms != other.tx_interval_ms: return False
+        if self.port_no != other.port_no: return False
+        if self.slot_num != other.slot_num: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_pdu_tx_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("tx_interval_ms = ");
+                q.text("%#x" % self.tx_interval_ms)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("slot_num = ");
+                q.text("%#x" % self.slot_num)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[31] = bsn_pdu_tx_request
+
+class bsn_set_ip_mask(bsn_header):
+    version = 1
+    type = 4
+    experimenter = 6035143
+    subtype = 0
+
+    def __init__(self, xid=None, index=None, mask=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if index != None:
+            self.index = index
+        else:
+            self.index = 0
+        if mask != None:
+            self.mask = mask
+        else:
+            self.mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!B", self.index))
+        packed.append('\x00' * 3)
+        packed.append(struct.pack("!L", self.mask))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_ip_mask()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 0)
+        obj.index = reader.read("!B")[0]
+        reader.skip(3)
+        obj.mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.index != other.index: return False
+        if self.mask != other.mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_ip_mask {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("index = ");
+                q.text("%#x" % self.index)
+                q.text(","); q.breakable()
+                q.text("mask = ");
+                q.text("%#x" % self.mask)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[0] = bsn_set_ip_mask
+
+class bsn_set_l2_table_reply(bsn_header):
+    version = 1
+    type = 4
+    experimenter = 6035143
+    subtype = 24
+
+    def __init__(self, xid=None, l2_table_enable=None, l2_table_priority=None, status=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if l2_table_enable != None:
+            self.l2_table_enable = l2_table_enable
+        else:
+            self.l2_table_enable = 0
+        if l2_table_priority != None:
+            self.l2_table_priority = l2_table_priority
+        else:
+            self.l2_table_priority = 0
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!B", self.l2_table_enable))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!H", self.l2_table_priority))
+        packed.append(struct.pack("!L", self.status))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_l2_table_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 24)
+        obj.l2_table_enable = reader.read("!B")[0]
+        reader.skip(1)
+        obj.l2_table_priority = reader.read("!H")[0]
+        obj.status = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.l2_table_enable != other.l2_table_enable: return False
+        if self.l2_table_priority != other.l2_table_priority: return False
+        if self.status != other.status: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_l2_table_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("l2_table_enable = ");
+                q.text("%#x" % self.l2_table_enable)
+                q.text(","); q.breakable()
+                q.text("l2_table_priority = ");
+                q.text("%#x" % self.l2_table_priority)
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[24] = bsn_set_l2_table_reply
+
+class bsn_set_l2_table_request(bsn_header):
+    version = 1
+    type = 4
+    experimenter = 6035143
+    subtype = 12
+
+    def __init__(self, xid=None, l2_table_enable=None, l2_table_priority=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if l2_table_enable != None:
+            self.l2_table_enable = l2_table_enable
+        else:
+            self.l2_table_enable = 0
+        if l2_table_priority != None:
+            self.l2_table_priority = l2_table_priority
+        else:
+            self.l2_table_priority = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!B", self.l2_table_enable))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!H", self.l2_table_priority))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_l2_table_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 12)
+        obj.l2_table_enable = reader.read("!B")[0]
+        reader.skip(1)
+        obj.l2_table_priority = reader.read("!H")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.l2_table_enable != other.l2_table_enable: return False
+        if self.l2_table_priority != other.l2_table_priority: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_l2_table_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("l2_table_enable = ");
+                q.text("%#x" % self.l2_table_enable)
+                q.text(","); q.breakable()
+                q.text("l2_table_priority = ");
+                q.text("%#x" % self.l2_table_priority)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[12] = bsn_set_l2_table_request
+
+class bsn_set_mirroring(bsn_header):
+    version = 1
+    type = 4
+    experimenter = 6035143
+    subtype = 3
+
+    def __init__(self, xid=None, report_mirror_ports=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if report_mirror_ports != None:
+            self.report_mirror_ports = report_mirror_ports
+        else:
+            self.report_mirror_ports = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!B", self.report_mirror_ports))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_mirroring()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 3)
+        obj.report_mirror_ports = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.report_mirror_ports != other.report_mirror_ports: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_mirroring {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("report_mirror_ports = ");
+                q.text("%#x" % self.report_mirror_ports)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[3] = bsn_set_mirroring
+
+class bsn_set_pktin_suppression_reply(bsn_header):
+    version = 1
+    type = 4
+    experimenter = 6035143
+    subtype = 25
+
+    def __init__(self, xid=None, status=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.status))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_pktin_suppression_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 25)
+        obj.status = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.status != other.status: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_pktin_suppression_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[25] = bsn_set_pktin_suppression_reply
+
+class bsn_set_pktin_suppression_request(bsn_header):
+    version = 1
+    type = 4
+    experimenter = 6035143
+    subtype = 11
+
+    def __init__(self, xid=None, enabled=None, idle_timeout=None, hard_timeout=None, priority=None, cookie=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if enabled != None:
+            self.enabled = enabled
+        else:
+            self.enabled = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!B", self.enabled))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!Q", self.cookie))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_pktin_suppression_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 11)
+        obj.enabled = reader.read("!B")[0]
+        reader.skip(1)
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.cookie = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.enabled != other.enabled: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.priority != other.priority: return False
+        if self.cookie != other.cookie: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_pktin_suppression_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("enabled = ");
+                q.text("%#x" % self.enabled)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[11] = bsn_set_pktin_suppression_request
+
+class bsn_shell_command(bsn_header):
+    version = 1
+    type = 4
+    experimenter = 6035143
+    subtype = 6
+
+    def __init__(self, xid=None, service=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if service != None:
+            self.service = service
+        else:
+            self.service = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.service))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_shell_command()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 6)
+        obj.service = reader.read("!L")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.service != other.service: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_shell_command {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("service = ");
+                q.text("%#x" % self.service)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[6] = bsn_shell_command
+
+class bsn_shell_output(bsn_header):
+    version = 1
+    type = 4
+    experimenter = 6035143
+    subtype = 7
+
+    def __init__(self, xid=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_shell_output()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 7)
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_shell_output {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[7] = bsn_shell_output
+
+class bsn_shell_status(bsn_header):
+    version = 1
+    type = 4
+    experimenter = 6035143
+    subtype = 8
+
+    def __init__(self, xid=None, status=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.status))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_shell_status()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 8)
+        obj.status = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.status != other.status: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_shell_status {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[8] = bsn_shell_status
+
+class experimenter_stats_reply(stats_reply):
+    subtypes = {}
+
+    version = 1
+    type = 17
+    stats_type = 65535
+
+    def __init__(self, xid=None, flags=None, experimenter=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 12)
+        subclass = experimenter_stats_reply.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = experimenter_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 17)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        obj.experimenter = reader.read("!L")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.experimenter != other.experimenter: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[65535] = experimenter_stats_reply
+
+class bsn_stats_reply(experimenter_stats_reply):
+    subtypes = {}
+
+    version = 1
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+
+    def __init__(self, xid=None, flags=None, subtype=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 20)
+        subclass = bsn_stats_reply.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = bsn_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        obj.subtype = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+experimenter_stats_reply.subtypes[6035143] = bsn_stats_reply
+
+class experimenter_stats_request(stats_request):
+    subtypes = {}
+
+    version = 1
+    type = 16
+    stats_type = 65535
+
+    def __init__(self, xid=None, flags=None, experimenter=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 12)
+        subclass = experimenter_stats_request.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = experimenter_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 16)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        obj.experimenter = reader.read("!L")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.experimenter != other.experimenter: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[65535] = experimenter_stats_request
+
+class bsn_stats_request(experimenter_stats_request):
+    subtypes = {}
+
+    version = 1
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+
+    def __init__(self, xid=None, flags=None, subtype=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 20)
+        subclass = bsn_stats_request.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = bsn_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        obj.subtype = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+experimenter_stats_request.subtypes[6035143] = bsn_stats_request
+
+class bsn_virtual_port_create_reply(bsn_header):
+    version = 1
+    type = 4
+    experimenter = 6035143
+    subtype = 16
+
+    def __init__(self, xid=None, status=None, vport_no=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        if vport_no != None:
+            self.vport_no = vport_no
+        else:
+            self.vport_no = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.status))
+        packed.append(struct.pack("!L", self.vport_no))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_virtual_port_create_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 16)
+        obj.status = reader.read("!L")[0]
+        obj.vport_no = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.status != other.status: return False
+        if self.vport_no != other.vport_no: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_virtual_port_create_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+                q.text(","); q.breakable()
+                q.text("vport_no = ");
+                q.text("%#x" % self.vport_no)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[16] = bsn_virtual_port_create_reply
+
+class bsn_virtual_port_create_request(bsn_header):
+    version = 1
+    type = 4
+    experimenter = 6035143
+    subtype = 15
+
+    def __init__(self, xid=None, vport=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if vport != None:
+            self.vport = vport
+        else:
+            self.vport = ofp.bsn_vport()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(self.vport.pack())
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_virtual_port_create_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 15)
+        obj.vport = ofp.bsn_vport.unpack(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.vport != other.vport: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_virtual_port_create_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("vport = ");
+                q.pp(self.vport)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[15] = bsn_virtual_port_create_request
+
+class bsn_virtual_port_remove_reply(bsn_header):
+    version = 1
+    type = 4
+    experimenter = 6035143
+    subtype = 26
+
+    def __init__(self, xid=None, status=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.status))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_virtual_port_remove_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 26)
+        obj.status = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.status != other.status: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_virtual_port_remove_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[26] = bsn_virtual_port_remove_reply
+
+class bsn_virtual_port_remove_request(bsn_header):
+    version = 1
+    type = 4
+    experimenter = 6035143
+    subtype = 17
+
+    def __init__(self, xid=None, vport_no=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if vport_no != None:
+            self.vport_no = vport_no
+        else:
+            self.vport_no = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.vport_no))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_virtual_port_remove_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 17)
+        obj.vport_no = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.vport_no != other.vport_no: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_virtual_port_remove_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("vport_no = ");
+                q.text("%#x" % self.vport_no)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[17] = bsn_virtual_port_remove_request
+
+class desc_stats_reply(stats_reply):
+    version = 1
+    type = 17
+    stats_type = 0
+
+    def __init__(self, xid=None, flags=None, mfr_desc=None, hw_desc=None, sw_desc=None, serial_num=None, dp_desc=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if mfr_desc != None:
+            self.mfr_desc = mfr_desc
+        else:
+            self.mfr_desc = ""
+        if hw_desc != None:
+            self.hw_desc = hw_desc
+        else:
+            self.hw_desc = ""
+        if sw_desc != None:
+            self.sw_desc = sw_desc
+        else:
+            self.sw_desc = ""
+        if serial_num != None:
+            self.serial_num = serial_num
+        else:
+            self.serial_num = ""
+        if dp_desc != None:
+            self.dp_desc = dp_desc
+        else:
+            self.dp_desc = ""
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(struct.pack("!256s", self.mfr_desc))
+        packed.append(struct.pack("!256s", self.hw_desc))
+        packed.append(struct.pack("!256s", self.sw_desc))
+        packed.append(struct.pack("!32s", self.serial_num))
+        packed.append(struct.pack("!256s", self.dp_desc))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = desc_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 17)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 0)
+        obj.flags = reader.read("!H")[0]
+        obj.mfr_desc = reader.read("!256s")[0].rstrip("\x00")
+        obj.hw_desc = reader.read("!256s")[0].rstrip("\x00")
+        obj.sw_desc = reader.read("!256s")[0].rstrip("\x00")
+        obj.serial_num = reader.read("!32s")[0].rstrip("\x00")
+        obj.dp_desc = reader.read("!256s")[0].rstrip("\x00")
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.mfr_desc != other.mfr_desc: return False
+        if self.hw_desc != other.hw_desc: return False
+        if self.sw_desc != other.sw_desc: return False
+        if self.serial_num != other.serial_num: return False
+        if self.dp_desc != other.dp_desc: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("desc_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("mfr_desc = ");
+                q.pp(self.mfr_desc)
+                q.text(","); q.breakable()
+                q.text("hw_desc = ");
+                q.pp(self.hw_desc)
+                q.text(","); q.breakable()
+                q.text("sw_desc = ");
+                q.pp(self.sw_desc)
+                q.text(","); q.breakable()
+                q.text("serial_num = ");
+                q.pp(self.serial_num)
+                q.text(","); q.breakable()
+                q.text("dp_desc = ");
+                q.pp(self.dp_desc)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[0] = desc_stats_reply
+
+class desc_stats_request(stats_request):
+    version = 1
+    type = 16
+    stats_type = 0
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = desc_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 16)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 0)
+        obj.flags = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("desc_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[0] = desc_stats_request
+
+class echo_reply(message):
+    version = 1
+    type = 3
+
+    def __init__(self, xid=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = echo_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 3)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("echo_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[3] = echo_reply
+
+class echo_request(message):
+    version = 1
+    type = 2
+
+    def __init__(self, xid=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = echo_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 2)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("echo_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[2] = echo_request
+
+class features_reply(message):
+    version = 1
+    type = 6
+
+    def __init__(self, xid=None, datapath_id=None, n_buffers=None, n_tables=None, capabilities=None, actions=None, ports=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if datapath_id != None:
+            self.datapath_id = datapath_id
+        else:
+            self.datapath_id = 0
+        if n_buffers != None:
+            self.n_buffers = n_buffers
+        else:
+            self.n_buffers = 0
+        if n_tables != None:
+            self.n_tables = n_tables
+        else:
+            self.n_tables = 0
+        if capabilities != None:
+            self.capabilities = capabilities
+        else:
+            self.capabilities = 0
+        if actions != None:
+            self.actions = actions
+        else:
+            self.actions = 0
+        if ports != None:
+            self.ports = ports
+        else:
+            self.ports = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!Q", self.datapath_id))
+        packed.append(struct.pack("!L", self.n_buffers))
+        packed.append(struct.pack("!B", self.n_tables))
+        packed.append('\x00' * 3)
+        packed.append(struct.pack("!L", self.capabilities))
+        packed.append(struct.pack("!L", self.actions))
+        packed.append(loxi.generic_util.pack_list(self.ports))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = features_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 6)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.datapath_id = reader.read("!Q")[0]
+        obj.n_buffers = reader.read("!L")[0]
+        obj.n_tables = reader.read("!B")[0]
+        reader.skip(3)
+        obj.capabilities = reader.read("!L")[0]
+        obj.actions = reader.read("!L")[0]
+        obj.ports = loxi.generic_util.unpack_list(reader, ofp.common.port_desc.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.datapath_id != other.datapath_id: return False
+        if self.n_buffers != other.n_buffers: return False
+        if self.n_tables != other.n_tables: return False
+        if self.capabilities != other.capabilities: return False
+        if self.actions != other.actions: return False
+        if self.ports != other.ports: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("features_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("datapath_id = ");
+                q.text("%#x" % self.datapath_id)
+                q.text(","); q.breakable()
+                q.text("n_buffers = ");
+                q.text("%#x" % self.n_buffers)
+                q.text(","); q.breakable()
+                q.text("n_tables = ");
+                q.text("%#x" % self.n_tables)
+                q.text(","); q.breakable()
+                q.text("capabilities = ");
+                q.text("%#x" % self.capabilities)
+                q.text(","); q.breakable()
+                q.text("actions = ");
+                q.text("%#x" % self.actions)
+                q.text(","); q.breakable()
+                q.text("ports = ");
+                q.pp(self.ports)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[6] = features_reply
+
+class features_request(message):
+    version = 1
+    type = 5
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = features_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 5)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("features_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+message.subtypes[5] = features_request
+
+class flow_mod(message):
+    subtypes = {}
+
+    version = 1
+    type = 14
+
+    def __init__(self, xid=None, match=None, cookie=None, _command=None, idle_timeout=None, hard_timeout=None, priority=None, buffer_id=None, out_port=None, flags=None, actions=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if _command != None:
+            self._command = _command
+        else:
+            self._command = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if actions != None:
+            self.actions = actions
+        else:
+            self.actions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(self.match.pack())
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(util.pack_fm_cmd(self._command))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(loxi.generic_util.pack_list(self.actions))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 56)
+        subclass = flow_mod.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = flow_mod()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 14)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.match = ofp.match.unpack(reader)
+        obj.cookie = reader.read("!Q")[0]
+        obj._command = util.unpack_fm_cmd(reader)
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.out_port = util.unpack_port_no(reader)
+        obj.flags = reader.read("!H")[0]
+        obj.actions = loxi.generic_util.unpack_list(reader, ofp.action.action.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.match != other.match: return False
+        if self.cookie != other.cookie: return False
+        if self._command != other._command: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.priority != other.priority: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.out_port != other.out_port: return False
+        if self.flags != other.flags: return False
+        if self.actions != other.actions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_mod {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("actions = ");
+                q.pp(self.actions)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[14] = flow_mod
+
+class flow_add(flow_mod):
+    version = 1
+    type = 14
+    _command = 0
+
+    def __init__(self, xid=None, match=None, cookie=None, idle_timeout=None, hard_timeout=None, priority=None, buffer_id=None, out_port=None, flags=None, actions=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if actions != None:
+            self.actions = actions
+        else:
+            self.actions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(self.match.pack())
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(util.pack_fm_cmd(self._command))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(loxi.generic_util.pack_list(self.actions))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_add()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 14)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.match = ofp.match.unpack(reader)
+        obj.cookie = reader.read("!Q")[0]
+        __command = util.unpack_fm_cmd(reader)
+        assert(__command == 0)
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.out_port = util.unpack_port_no(reader)
+        obj.flags = reader.read("!H")[0]
+        obj.actions = loxi.generic_util.unpack_list(reader, ofp.action.action.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.match != other.match: return False
+        if self.cookie != other.cookie: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.priority != other.priority: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.out_port != other.out_port: return False
+        if self.flags != other.flags: return False
+        if self.actions != other.actions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_add {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("actions = ");
+                q.pp(self.actions)
+            q.breakable()
+        q.text('}')
+
+flow_mod.subtypes[0] = flow_add
+
+class flow_delete(flow_mod):
+    version = 1
+    type = 14
+    _command = 3
+
+    def __init__(self, xid=None, match=None, cookie=None, idle_timeout=None, hard_timeout=None, priority=None, buffer_id=None, out_port=None, flags=None, actions=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if actions != None:
+            self.actions = actions
+        else:
+            self.actions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(self.match.pack())
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(util.pack_fm_cmd(self._command))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(loxi.generic_util.pack_list(self.actions))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_delete()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 14)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.match = ofp.match.unpack(reader)
+        obj.cookie = reader.read("!Q")[0]
+        __command = util.unpack_fm_cmd(reader)
+        assert(__command == 3)
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.out_port = util.unpack_port_no(reader)
+        obj.flags = reader.read("!H")[0]
+        obj.actions = loxi.generic_util.unpack_list(reader, ofp.action.action.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.match != other.match: return False
+        if self.cookie != other.cookie: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.priority != other.priority: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.out_port != other.out_port: return False
+        if self.flags != other.flags: return False
+        if self.actions != other.actions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_delete {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("actions = ");
+                q.pp(self.actions)
+            q.breakable()
+        q.text('}')
+
+flow_mod.subtypes[3] = flow_delete
+
+class flow_delete_strict(flow_mod):
+    version = 1
+    type = 14
+    _command = 4
+
+    def __init__(self, xid=None, match=None, cookie=None, idle_timeout=None, hard_timeout=None, priority=None, buffer_id=None, out_port=None, flags=None, actions=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if actions != None:
+            self.actions = actions
+        else:
+            self.actions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(self.match.pack())
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(util.pack_fm_cmd(self._command))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(loxi.generic_util.pack_list(self.actions))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_delete_strict()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 14)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.match = ofp.match.unpack(reader)
+        obj.cookie = reader.read("!Q")[0]
+        __command = util.unpack_fm_cmd(reader)
+        assert(__command == 4)
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.out_port = util.unpack_port_no(reader)
+        obj.flags = reader.read("!H")[0]
+        obj.actions = loxi.generic_util.unpack_list(reader, ofp.action.action.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.match != other.match: return False
+        if self.cookie != other.cookie: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.priority != other.priority: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.out_port != other.out_port: return False
+        if self.flags != other.flags: return False
+        if self.actions != other.actions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_delete_strict {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("actions = ");
+                q.pp(self.actions)
+            q.breakable()
+        q.text('}')
+
+flow_mod.subtypes[4] = flow_delete_strict
+
+class flow_mod_failed_error_msg(error_msg):
+    version = 1
+    type = 1
+    err_type = 3
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_mod_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 3)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_mod_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[3] = flow_mod_failed_error_msg
+
+class flow_modify(flow_mod):
+    version = 1
+    type = 14
+    _command = 1
+
+    def __init__(self, xid=None, match=None, cookie=None, idle_timeout=None, hard_timeout=None, priority=None, buffer_id=None, out_port=None, flags=None, actions=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if actions != None:
+            self.actions = actions
+        else:
+            self.actions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(self.match.pack())
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(util.pack_fm_cmd(self._command))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(loxi.generic_util.pack_list(self.actions))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_modify()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 14)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.match = ofp.match.unpack(reader)
+        obj.cookie = reader.read("!Q")[0]
+        __command = util.unpack_fm_cmd(reader)
+        assert(__command == 1)
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.out_port = util.unpack_port_no(reader)
+        obj.flags = reader.read("!H")[0]
+        obj.actions = loxi.generic_util.unpack_list(reader, ofp.action.action.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.match != other.match: return False
+        if self.cookie != other.cookie: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.priority != other.priority: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.out_port != other.out_port: return False
+        if self.flags != other.flags: return False
+        if self.actions != other.actions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_modify {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("actions = ");
+                q.pp(self.actions)
+            q.breakable()
+        q.text('}')
+
+flow_mod.subtypes[1] = flow_modify
+
+class flow_modify_strict(flow_mod):
+    version = 1
+    type = 14
+    _command = 2
+
+    def __init__(self, xid=None, match=None, cookie=None, idle_timeout=None, hard_timeout=None, priority=None, buffer_id=None, out_port=None, flags=None, actions=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if actions != None:
+            self.actions = actions
+        else:
+            self.actions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(self.match.pack())
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(util.pack_fm_cmd(self._command))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(loxi.generic_util.pack_list(self.actions))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_modify_strict()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 14)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.match = ofp.match.unpack(reader)
+        obj.cookie = reader.read("!Q")[0]
+        __command = util.unpack_fm_cmd(reader)
+        assert(__command == 2)
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.out_port = util.unpack_port_no(reader)
+        obj.flags = reader.read("!H")[0]
+        obj.actions = loxi.generic_util.unpack_list(reader, ofp.action.action.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.match != other.match: return False
+        if self.cookie != other.cookie: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.priority != other.priority: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.out_port != other.out_port: return False
+        if self.flags != other.flags: return False
+        if self.actions != other.actions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_modify_strict {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("actions = ");
+                q.pp(self.actions)
+            q.breakable()
+        q.text('}')
+
+flow_mod.subtypes[2] = flow_modify_strict
+
+class flow_removed(message):
+    version = 1
+    type = 11
+
+    def __init__(self, xid=None, match=None, cookie=None, priority=None, reason=None, duration_sec=None, duration_nsec=None, idle_timeout=None, packet_count=None, byte_count=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if reason != None:
+            self.reason = reason
+        else:
+            self.reason = 0
+        if duration_sec != None:
+            self.duration_sec = duration_sec
+        else:
+            self.duration_sec = 0
+        if duration_nsec != None:
+            self.duration_nsec = duration_nsec
+        else:
+            self.duration_nsec = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if packet_count != None:
+            self.packet_count = packet_count
+        else:
+            self.packet_count = 0
+        if byte_count != None:
+            self.byte_count = byte_count
+        else:
+            self.byte_count = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(self.match.pack())
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!B", self.reason))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!L", self.duration_sec))
+        packed.append(struct.pack("!L", self.duration_nsec))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!Q", self.packet_count))
+        packed.append(struct.pack("!Q", self.byte_count))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_removed()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 11)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.match = ofp.match.unpack(reader)
+        obj.cookie = reader.read("!Q")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.reason = reader.read("!B")[0]
+        reader.skip(1)
+        obj.duration_sec = reader.read("!L")[0]
+        obj.duration_nsec = reader.read("!L")[0]
+        obj.idle_timeout = reader.read("!H")[0]
+        reader.skip(2)
+        obj.packet_count = reader.read("!Q")[0]
+        obj.byte_count = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.match != other.match: return False
+        if self.cookie != other.cookie: return False
+        if self.priority != other.priority: return False
+        if self.reason != other.reason: return False
+        if self.duration_sec != other.duration_sec: return False
+        if self.duration_nsec != other.duration_nsec: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.packet_count != other.packet_count: return False
+        if self.byte_count != other.byte_count: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_removed {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("reason = ");
+                q.text("%#x" % self.reason)
+                q.text(","); q.breakable()
+                q.text("duration_sec = ");
+                q.text("%#x" % self.duration_sec)
+                q.text(","); q.breakable()
+                q.text("duration_nsec = ");
+                q.text("%#x" % self.duration_nsec)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("packet_count = ");
+                q.text("%#x" % self.packet_count)
+                q.text(","); q.breakable()
+                q.text("byte_count = ");
+                q.text("%#x" % self.byte_count)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[11] = flow_removed
+
+class flow_stats_reply(stats_reply):
+    version = 1
+    type = 17
+    stats_type = 1
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 17)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 1)
+        obj.flags = reader.read("!H")[0]
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.flow_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[1] = flow_stats_reply
+
+class flow_stats_request(stats_request):
+    version = 1
+    type = 16
+    stats_type = 1
+
+    def __init__(self, xid=None, flags=None, match=None, table_id=None, out_port=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(self.match.pack())
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append('\x00' * 1)
+        packed.append(util.pack_port_no(self.out_port))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 16)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 1)
+        obj.flags = reader.read("!H")[0]
+        obj.match = ofp.match.unpack(reader)
+        obj.table_id = reader.read("!B")[0]
+        reader.skip(1)
+        obj.out_port = util.unpack_port_no(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.match != other.match: return False
+        if self.table_id != other.table_id: return False
+        if self.out_port != other.out_port: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[1] = flow_stats_request
+
+class get_config_reply(message):
+    version = 1
+    type = 8
+
+    def __init__(self, xid=None, flags=None, miss_send_len=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if miss_send_len != None:
+            self.miss_send_len = miss_send_len
+        else:
+            self.miss_send_len = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(struct.pack("!H", self.miss_send_len))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = get_config_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 8)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.flags = reader.read("!H")[0]
+        obj.miss_send_len = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.miss_send_len != other.miss_send_len: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("get_config_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("miss_send_len = ");
+                q.text("%#x" % self.miss_send_len)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[8] = get_config_reply
+
+class get_config_request(message):
+    version = 1
+    type = 7
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = get_config_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 7)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("get_config_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+message.subtypes[7] = get_config_request
+
+class hello(message):
+    version = 1
+    type = 0
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = hello()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 0)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("hello {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+message.subtypes[0] = hello
+
+class hello_failed_error_msg(error_msg):
+    version = 1
+    type = 1
+    err_type = 0
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = hello_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 0)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("hello_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[0] = hello_failed_error_msg
+
+class nicira_header(experimenter):
+    subtypes = {}
+
+    version = 1
+    type = 4
+    experimenter = 8992
+
+    def __init__(self, xid=None, subtype=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 12)
+        subclass = nicira_header.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = nicira_header()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 8992)
+        obj.subtype = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("nicira_header {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+experimenter.subtypes[8992] = nicira_header
+
+class nicira_controller_role_reply(nicira_header):
+    version = 1
+    type = 4
+    experimenter = 8992
+    subtype = 11
+
+    def __init__(self, xid=None, role=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if role != None:
+            self.role = role
+        else:
+            self.role = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.role))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = nicira_controller_role_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 8992)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 11)
+        obj.role = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.role != other.role: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("nicira_controller_role_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("role = ");
+                q.text("%#x" % self.role)
+            q.breakable()
+        q.text('}')
+
+nicira_header.subtypes[11] = nicira_controller_role_reply
+
+class nicira_controller_role_request(nicira_header):
+    version = 1
+    type = 4
+    experimenter = 8992
+    subtype = 10
+
+    def __init__(self, xid=None, role=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if role != None:
+            self.role = role
+        else:
+            self.role = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.role))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = nicira_controller_role_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 8992)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 10)
+        obj.role = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.role != other.role: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("nicira_controller_role_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("role = ");
+                q.text("%#x" % self.role)
+            q.breakable()
+        q.text('}')
+
+nicira_header.subtypes[10] = nicira_controller_role_request
+
+class packet_in(message):
+    version = 1
+    type = 10
+
+    def __init__(self, xid=None, buffer_id=None, total_len=None, in_port=None, reason=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if total_len != None:
+            self.total_len = total_len
+        else:
+            self.total_len = 0
+        if in_port != None:
+            self.in_port = in_port
+        else:
+            self.in_port = 0
+        if reason != None:
+            self.reason = reason
+        else:
+            self.reason = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(struct.pack("!H", self.total_len))
+        packed.append(util.pack_port_no(self.in_port))
+        packed.append(struct.pack("!B", self.reason))
+        packed.append('\x00' * 1)
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = packet_in()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 10)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.total_len = reader.read("!H")[0]
+        obj.in_port = util.unpack_port_no(reader)
+        obj.reason = reader.read("!B")[0]
+        reader.skip(1)
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.total_len != other.total_len: return False
+        if self.in_port != other.in_port: return False
+        if self.reason != other.reason: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("packet_in {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("total_len = ");
+                q.text("%#x" % self.total_len)
+                q.text(","); q.breakable()
+                q.text("in_port = ");
+                q.text(util.pretty_port(self.in_port))
+                q.text(","); q.breakable()
+                q.text("reason = ");
+                q.text("%#x" % self.reason)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[10] = packet_in
+
+class packet_out(message):
+    version = 1
+    type = 13
+
+    def __init__(self, xid=None, buffer_id=None, in_port=None, actions=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if in_port != None:
+            self.in_port = in_port
+        else:
+            self.in_port = 0
+        if actions != None:
+            self.actions = actions
+        else:
+            self.actions = []
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(util.pack_port_no(self.in_port))
+        packed.append(struct.pack("!H", 0)) # placeholder for actions_len at index 6
+        packed.append(loxi.generic_util.pack_list(self.actions))
+        packed[6] = struct.pack("!H", len(packed[-1]))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = packet_out()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 13)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.in_port = util.unpack_port_no(reader)
+        _actions_len = reader.read("!H")[0]
+        obj.actions = loxi.generic_util.unpack_list(reader.slice(_actions_len), ofp.action.action.unpack)
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.in_port != other.in_port: return False
+        if self.actions != other.actions: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("packet_out {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("in_port = ");
+                q.text(util.pretty_port(self.in_port))
+                q.text(","); q.breakable()
+                q.text("actions = ");
+                q.pp(self.actions)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[13] = packet_out
+
+class port_mod(message):
+    version = 1
+    type = 15
+
+    def __init__(self, xid=None, port_no=None, hw_addr=None, config=None, mask=None, advertise=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if hw_addr != None:
+            self.hw_addr = hw_addr
+        else:
+            self.hw_addr = [0,0,0,0,0,0]
+        if config != None:
+            self.config = config
+        else:
+            self.config = 0
+        if mask != None:
+            self.mask = mask
+        else:
+            self.mask = 0
+        if advertise != None:
+            self.advertise = advertise
+        else:
+            self.advertise = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!6B", *self.hw_addr))
+        packed.append(struct.pack("!L", self.config))
+        packed.append(struct.pack("!L", self.mask))
+        packed.append(struct.pack("!L", self.advertise))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_mod()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 15)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.port_no = util.unpack_port_no(reader)
+        obj.hw_addr = list(reader.read('!6B'))
+        obj.config = reader.read("!L")[0]
+        obj.mask = reader.read("!L")[0]
+        obj.advertise = reader.read("!L")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.port_no != other.port_no: return False
+        if self.hw_addr != other.hw_addr: return False
+        if self.config != other.config: return False
+        if self.mask != other.mask: return False
+        if self.advertise != other.advertise: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_mod {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("hw_addr = ");
+                q.text(util.pretty_mac(self.hw_addr))
+                q.text(","); q.breakable()
+                q.text("config = ");
+                q.text("%#x" % self.config)
+                q.text(","); q.breakable()
+                q.text("mask = ");
+                q.text("%#x" % self.mask)
+                q.text(","); q.breakable()
+                q.text("advertise = ");
+                q.text("%#x" % self.advertise)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[15] = port_mod
+
+class port_mod_failed_error_msg(error_msg):
+    version = 1
+    type = 1
+    err_type = 4
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_mod_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 4)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_mod_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[4] = port_mod_failed_error_msg
+
+class port_stats_reply(stats_reply):
+    version = 1
+    type = 17
+    stats_type = 4
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 17)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 4)
+        obj.flags = reader.read("!H")[0]
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.port_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[4] = port_stats_reply
+
+class port_stats_request(stats_request):
+    version = 1
+    type = 16
+    stats_type = 4
+
+    def __init__(self, xid=None, flags=None, port_no=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append('\x00' * 6)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 16)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 4)
+        obj.flags = reader.read("!H")[0]
+        obj.port_no = util.unpack_port_no(reader)
+        reader.skip(6)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.port_no != other.port_no: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[4] = port_stats_request
+
+class port_status(message):
+    version = 1
+    type = 12
+
+    def __init__(self, xid=None, reason=None, desc=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if reason != None:
+            self.reason = reason
+        else:
+            self.reason = 0
+        if desc != None:
+            self.desc = desc
+        else:
+            self.desc = ofp.port_desc()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!B", self.reason))
+        packed.append('\x00' * 7)
+        packed.append(self.desc.pack())
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_status()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 12)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.reason = reader.read("!B")[0]
+        reader.skip(7)
+        obj.desc = ofp.port_desc.unpack(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.reason != other.reason: return False
+        if self.desc != other.desc: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_status {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("reason = ");
+                q.text("%#x" % self.reason)
+                q.text(","); q.breakable()
+                q.text("desc = ");
+                q.pp(self.desc)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[12] = port_status
+
+class queue_get_config_reply(message):
+    version = 1
+    type = 21
+
+    def __init__(self, xid=None, port=None, queues=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if port != None:
+            self.port = port
+        else:
+            self.port = 0
+        if queues != None:
+            self.queues = queues
+        else:
+            self.queues = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(util.pack_port_no(self.port))
+        packed.append('\x00' * 6)
+        packed.append(loxi.generic_util.pack_list(self.queues))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_get_config_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 21)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.port = util.unpack_port_no(reader)
+        reader.skip(6)
+        obj.queues = loxi.generic_util.unpack_list(reader, ofp.common.packet_queue.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.port != other.port: return False
+        if self.queues != other.queues: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_get_config_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("port = ");
+                q.text(util.pretty_port(self.port))
+                q.text(","); q.breakable()
+                q.text("queues = ");
+                q.pp(self.queues)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[21] = queue_get_config_reply
+
+class queue_get_config_request(message):
+    version = 1
+    type = 20
+
+    def __init__(self, xid=None, port=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if port != None:
+            self.port = port
+        else:
+            self.port = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(util.pack_port_no(self.port))
+        packed.append('\x00' * 2)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_get_config_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 20)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.port = util.unpack_port_no(reader)
+        reader.skip(2)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.port != other.port: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_get_config_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("port = ");
+                q.text(util.pretty_port(self.port))
+            q.breakable()
+        q.text('}')
+
+message.subtypes[20] = queue_get_config_request
+
+class queue_op_failed_error_msg(error_msg):
+    version = 1
+    type = 1
+    err_type = 5
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_op_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 5)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_op_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[5] = queue_op_failed_error_msg
+
+class queue_stats_reply(stats_reply):
+    version = 1
+    type = 17
+    stats_type = 5
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 17)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 5)
+        obj.flags = reader.read("!H")[0]
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.queue_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[5] = queue_stats_reply
+
+class queue_stats_request(stats_request):
+    version = 1
+    type = 16
+    stats_type = 5
+
+    def __init__(self, xid=None, flags=None, port_no=None, queue_id=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if queue_id != None:
+            self.queue_id = queue_id
+        else:
+            self.queue_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!L", self.queue_id))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 16)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 5)
+        obj.flags = reader.read("!H")[0]
+        obj.port_no = util.unpack_port_no(reader)
+        reader.skip(2)
+        obj.queue_id = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.port_no != other.port_no: return False
+        if self.queue_id != other.queue_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("queue_id = ");
+                q.text("%#x" % self.queue_id)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[5] = queue_stats_request
+
+class set_config(message):
+    version = 1
+    type = 9
+
+    def __init__(self, xid=None, flags=None, miss_send_len=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if miss_send_len != None:
+            self.miss_send_len = miss_send_len
+        else:
+            self.miss_send_len = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(struct.pack("!H", self.miss_send_len))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_config()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 9)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.flags = reader.read("!H")[0]
+        obj.miss_send_len = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.miss_send_len != other.miss_send_len: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_config {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("miss_send_len = ");
+                q.text("%#x" % self.miss_send_len)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[9] = set_config
+
+class table_mod(message):
+    version = 1
+    type = 22
+
+    def __init__(self, xid=None, table_id=None, config=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if config != None:
+            self.config = config
+        else:
+            self.config = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append('\x00' * 3)
+        packed.append(struct.pack("!L", self.config))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_mod()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 22)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.table_id = reader.read("!B")[0]
+        reader.skip(3)
+        obj.config = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.table_id != other.table_id: return False
+        if self.config != other.config: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_mod {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("config = ");
+                q.text("%#x" % self.config)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[22] = table_mod
+
+class table_stats_reply(stats_reply):
+    version = 1
+    type = 17
+    stats_type = 3
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 17)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 3)
+        obj.flags = reader.read("!H")[0]
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.table_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[3] = table_stats_reply
+
+class table_stats_request(stats_request):
+    version = 1
+    type = 16
+    stats_type = 3
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 1)
+        _type = reader.read("!B")[0]
+        assert(_type == 16)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 3)
+        obj.flags = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[3] = table_stats_request
+
+
+def parse_header(buf):
+    if len(buf) < 8:
+        raise loxi.ProtocolError("too short to be an OpenFlow message")
+    return struct.unpack_from("!BBHL", buf)
+
+def parse_message(buf):
+    msg_ver, msg_type, msg_len, msg_xid = parse_header(buf)
+    if msg_ver != ofp.OFP_VERSION and msg_type != ofp.OFPT_HELLO:
+        raise loxi.ProtocolError("wrong OpenFlow version (expected %d, got %d)" % (ofp.OFP_VERSION, msg_ver))
+    if len(buf) != msg_len:
+        raise loxi.ProtocolError("incorrect message size")
+    return message.unpack(loxi.generic_util.OFReader(buf))
diff --git a/Fabric/Utilities/src/python/loxi/of10/util.py b/Fabric/Utilities/src/python/loxi/of10/util.py
new file mode 100644
index 0000000..2e68b0b
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of10/util.py
@@ -0,0 +1,142 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+# Automatically generated by LOXI from template util.py
+# Do not modify
+
+import struct
+import loxi
+import const
+import common
+import action
+
+def pretty_mac(mac):
+    return ':'.join(["%02x" % x for x in mac])
+
+def pretty_ipv4(v):
+    return "%d.%d.%d.%d" % ((v >> 24) & 0xFF, (v >> 16) & 0xFF, (v >> 8) & 0xFF, v & 0xFF)
+
+def pretty_flags(v, flag_names):
+    set_flags = []
+    for flag_name in flag_names:
+        flag_value = getattr(const, flag_name)
+        if v & flag_value == flag_value:
+            set_flags.append(flag_name)
+        elif v & flag_value:
+            set_flags.append('%s&%#x' % (flag_name, v & flag_value))
+        v &= ~flag_value
+    if v:
+        set_flags.append("%#x" % v)
+    return '|'.join(set_flags) or '0'
+
+def pretty_wildcards(v):
+    if v == const.OFPFW_ALL:
+        return 'OFPFW_ALL'
+    flag_names = ['OFPFW_IN_PORT', 'OFPFW_DL_VLAN', 'OFPFW_DL_SRC', 'OFPFW_DL_DST',
+                  'OFPFW_DL_TYPE', 'OFPFW_NW_PROTO', 'OFPFW_TP_SRC', 'OFPFW_TP_DST',
+                  'OFPFW_NW_SRC_MASK', 'OFPFW_NW_DST_MASK', 'OFPFW_DL_VLAN_PCP',
+                  'OFPFW_NW_TOS']
+    return pretty_flags(v, flag_names)
+
+def pretty_port(v):
+    named_ports = [(k,v2) for (k,v2) in const.__dict__.iteritems() if k.startswith('OFPP_')]
+    for (k, v2) in named_ports:
+        if v == v2:
+            return k
+    return v
+
+def pack_port_no(value):
+    return struct.pack("!H", value)
+
+def unpack_port_no(reader):
+    return reader.read("!H")[0]
+
+def pack_fm_cmd(value):
+    return struct.pack("!H", value)
+
+def unpack_fm_cmd(reader):
+    return reader.read("!H")[0]
+
+def init_wc_bmap():
+    return const.OFPFW_ALL
+
+def pack_wc_bmap(value):
+    return struct.pack("!L", value)
+
+def unpack_wc_bmap(reader):
+    return reader.read("!L")[0]
+
+def init_match_bmap():
+    return const.OFPFW_ALL
+
+def pack_match_bmap(value):
+    return struct.pack("!L", value)
+
+def unpack_match_bmap(reader):
+    return reader.read("!L")[0]
+
+MASK64 = (1 << 64) - 1
+
+def pack_bitmap_128(value):
+    x = 0l
+    for y in value:
+        x |= 1 << y
+    return struct.pack("!QQ", (x >> 64) & MASK64, x & MASK64)
+
+def unpack_bitmap_128(reader):
+    hi, lo = reader.read("!QQ")
+    x = (hi << 64) | lo
+    i = 0
+    value = set()
+    while x != 0:
+        if x & 1 == 1:
+            value.add(i)
+        i += 1
+        x >>= 1
+    return value
+
+def pack_bitmap_512(value):
+    words = [0] * 8
+    for v in value:
+        assert v < 512
+        words[7-v/64] |= 1 << (v % 64)
+    return struct.pack("!8Q", *words)
+
+def unpack_bitmap_512(reader):
+    words = reader.read("!8Q")
+    x = 0l
+    for word in words:
+        x <<= 64
+        x |= word
+    i = 0
+    value = set()
+    while x != 0:
+        if x & 1 == 1:
+            value.add(i)
+        i += 1
+        x >>= 1
+    return value
+
+def pack_checksum_128(value):
+    return struct.pack("!QQ", (value >> 64) & MASK64, value & MASK64)
+
+def unpack_checksum_128(reader):
+    hi, lo = reader.read("!QQ")
+    return (hi << 64) | lo
diff --git a/Fabric/Utilities/src/python/loxi/of11/__init__.py b/Fabric/Utilities/src/python/loxi/of11/__init__.py
new file mode 100644
index 0000000..605c1fb
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of11/__init__.py
@@ -0,0 +1,32 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template init.py
+# Do not modify
+
+import const
+import action
+import message
+import instruction
+import common
+from const import *
+from common import *
+from loxi import ProtocolError
diff --git a/Fabric/Utilities/src/python/loxi/of11/action.py b/Fabric/Utilities/src/python/loxi/of11/action.py
new file mode 100644
index 0000000..3ad2c90
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of11/action.py
@@ -0,0 +1,1678 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of11']
+
+class action(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = action.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = action()
+        obj.type = reader.read("!H")[0]
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("action {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class experimenter(action):
+    subtypes = {}
+
+    type = 65535
+
+    def __init__(self, experimenter=None, data=None):
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 4)
+        subclass = experimenter.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = experimenter()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.experimenter = reader.read("!L")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.experimenter != other.experimenter: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[65535] = experimenter
+
+class bsn(experimenter):
+    subtypes = {}
+
+    type = 65535
+    experimenter = 6035143
+
+    def __init__(self, subtype=None):
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 8)
+        subclass = bsn.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = bsn()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        obj.subtype = reader.read("!L")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+experimenter.subtypes[6035143] = bsn
+
+class bsn_checksum(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 4
+
+    def __init__(self, checksum=None):
+        if checksum != None:
+            self.checksum = checksum
+        else:
+            self.checksum = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(util.pack_checksum_128(self.checksum))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_checksum()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 4)
+        obj.checksum = util.unpack_checksum_128(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.checksum != other.checksum: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_checksum {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("checksum = ");
+                q.pp(self.checksum)
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[4] = bsn_checksum
+
+class bsn_mirror(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 1
+
+    def __init__(self, dest_port=None, vlan_tag=None, copy_stage=None):
+        if dest_port != None:
+            self.dest_port = dest_port
+        else:
+            self.dest_port = 0
+        if vlan_tag != None:
+            self.vlan_tag = vlan_tag
+        else:
+            self.vlan_tag = 0
+        if copy_stage != None:
+            self.copy_stage = copy_stage
+        else:
+            self.copy_stage = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.dest_port))
+        packed.append(struct.pack("!L", self.vlan_tag))
+        packed.append(struct.pack("!B", self.copy_stage))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_mirror()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 1)
+        obj.dest_port = reader.read("!L")[0]
+        obj.vlan_tag = reader.read("!L")[0]
+        obj.copy_stage = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.dest_port != other.dest_port: return False
+        if self.vlan_tag != other.vlan_tag: return False
+        if self.copy_stage != other.copy_stage: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_mirror {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("dest_port = ");
+                q.text("%#x" % self.dest_port)
+                q.text(","); q.breakable()
+                q.text("vlan_tag = ");
+                q.text("%#x" % self.vlan_tag)
+                q.text(","); q.breakable()
+                q.text("copy_stage = ");
+                q.text("%#x" % self.copy_stage)
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[1] = bsn_mirror
+
+class bsn_set_tunnel_dst(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 2
+
+    def __init__(self, dst=None):
+        if dst != None:
+            self.dst = dst
+        else:
+            self.dst = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.dst))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_tunnel_dst()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 2)
+        obj.dst = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.dst != other.dst: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_tunnel_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("dst = ");
+                q.text("%#x" % self.dst)
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[2] = bsn_set_tunnel_dst
+
+class copy_ttl_in(action):
+    type = 12
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = copy_ttl_in()
+        _type = reader.read("!H")[0]
+        assert(_type == 12)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("copy_ttl_in {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action.subtypes[12] = copy_ttl_in
+
+class copy_ttl_out(action):
+    type = 11
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = copy_ttl_out()
+        _type = reader.read("!H")[0]
+        assert(_type == 11)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("copy_ttl_out {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action.subtypes[11] = copy_ttl_out
+
+class dec_mpls_ttl(action):
+    type = 16
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = dec_mpls_ttl()
+        _type = reader.read("!H")[0]
+        assert(_type == 16)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("dec_mpls_ttl {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action.subtypes[16] = dec_mpls_ttl
+
+class dec_nw_ttl(action):
+    type = 24
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = dec_nw_ttl()
+        _type = reader.read("!H")[0]
+        assert(_type == 24)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("dec_nw_ttl {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action.subtypes[24] = dec_nw_ttl
+
+class group(action):
+    type = 22
+
+    def __init__(self, group_id=None):
+        if group_id != None:
+            self.group_id = group_id
+        else:
+            self.group_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.group_id))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group()
+        _type = reader.read("!H")[0]
+        assert(_type == 22)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.group_id = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.group_id != other.group_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("group_id = ");
+                q.text("%#x" % self.group_id)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[22] = group
+
+class nicira(experimenter):
+    subtypes = {}
+
+    type = 65535
+    experimenter = 8992
+
+    def __init__(self, subtype=None):
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!H", self.subtype))
+        packed.append('\x00' * 2)
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 8)
+        subclass = nicira.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = nicira()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 8992)
+        obj.subtype = reader.read("!H")[0]
+        reader.skip(2)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("nicira {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+experimenter.subtypes[8992] = nicira
+
+class nicira_dec_ttl(nicira):
+    type = 65535
+    experimenter = 8992
+    subtype = 18
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!H", self.subtype))
+        packed.append('\x00' * 2)
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = nicira_dec_ttl()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 8992)
+        _subtype = reader.read("!H")[0]
+        assert(_subtype == 18)
+        reader.skip(2)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("nicira_dec_ttl {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+nicira.subtypes[18] = nicira_dec_ttl
+
+class output(action):
+    type = 0
+
+    def __init__(self, port=None, max_len=None):
+        if port != None:
+            self.port = port
+        else:
+            self.port = 0
+        if max_len != None:
+            self.max_len = max_len
+        else:
+            self.max_len = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(util.pack_port_no(self.port))
+        packed.append(struct.pack("!H", self.max_len))
+        packed.append('\x00' * 6)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = output()
+        _type = reader.read("!H")[0]
+        assert(_type == 0)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.port = util.unpack_port_no(reader)
+        obj.max_len = reader.read("!H")[0]
+        reader.skip(6)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.port != other.port: return False
+        if self.max_len != other.max_len: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("output {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("port = ");
+                q.text(util.pretty_port(self.port))
+                q.text(","); q.breakable()
+                q.text("max_len = ");
+                q.text("%#x" % self.max_len)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[0] = output
+
+class pop_mpls(action):
+    type = 20
+
+    def __init__(self, ethertype=None):
+        if ethertype != None:
+            self.ethertype = ethertype
+        else:
+            self.ethertype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!H", self.ethertype))
+        packed.append('\x00' * 2)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = pop_mpls()
+        _type = reader.read("!H")[0]
+        assert(_type == 20)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.ethertype = reader.read("!H")[0]
+        reader.skip(2)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.ethertype != other.ethertype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("pop_mpls {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("ethertype = ");
+                q.text("%#x" % self.ethertype)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[20] = pop_mpls
+
+class pop_vlan(action):
+    type = 18
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = pop_vlan()
+        _type = reader.read("!H")[0]
+        assert(_type == 18)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("pop_vlan {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action.subtypes[18] = pop_vlan
+
+class push_mpls(action):
+    type = 19
+
+    def __init__(self, ethertype=None):
+        if ethertype != None:
+            self.ethertype = ethertype
+        else:
+            self.ethertype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!H", self.ethertype))
+        packed.append('\x00' * 2)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = push_mpls()
+        _type = reader.read("!H")[0]
+        assert(_type == 19)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.ethertype = reader.read("!H")[0]
+        reader.skip(2)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.ethertype != other.ethertype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("push_mpls {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("ethertype = ");
+                q.text("%#x" % self.ethertype)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[19] = push_mpls
+
+class push_vlan(action):
+    type = 17
+
+    def __init__(self, ethertype=None):
+        if ethertype != None:
+            self.ethertype = ethertype
+        else:
+            self.ethertype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!H", self.ethertype))
+        packed.append('\x00' * 2)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = push_vlan()
+        _type = reader.read("!H")[0]
+        assert(_type == 17)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.ethertype = reader.read("!H")[0]
+        reader.skip(2)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.ethertype != other.ethertype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("push_vlan {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("ethertype = ");
+                q.text("%#x" % self.ethertype)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[17] = push_vlan
+
+class set_dl_dst(action):
+    type = 4
+
+    def __init__(self, dl_addr=None):
+        if dl_addr != None:
+            self.dl_addr = dl_addr
+        else:
+            self.dl_addr = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!6B", *self.dl_addr))
+        packed.append('\x00' * 6)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_dl_dst()
+        _type = reader.read("!H")[0]
+        assert(_type == 4)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.dl_addr = list(reader.read('!6B'))
+        reader.skip(6)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.dl_addr != other.dl_addr: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_dl_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("dl_addr = ");
+                q.text(util.pretty_mac(self.dl_addr))
+            q.breakable()
+        q.text('}')
+
+action.subtypes[4] = set_dl_dst
+
+class set_dl_src(action):
+    type = 3
+
+    def __init__(self, dl_addr=None):
+        if dl_addr != None:
+            self.dl_addr = dl_addr
+        else:
+            self.dl_addr = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!6B", *self.dl_addr))
+        packed.append('\x00' * 6)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_dl_src()
+        _type = reader.read("!H")[0]
+        assert(_type == 3)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.dl_addr = list(reader.read('!6B'))
+        reader.skip(6)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.dl_addr != other.dl_addr: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_dl_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("dl_addr = ");
+                q.text(util.pretty_mac(self.dl_addr))
+            q.breakable()
+        q.text('}')
+
+action.subtypes[3] = set_dl_src
+
+class set_mpls_label(action):
+    type = 13
+
+    def __init__(self, mpls_label=None):
+        if mpls_label != None:
+            self.mpls_label = mpls_label
+        else:
+            self.mpls_label = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.mpls_label))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_mpls_label()
+        _type = reader.read("!H")[0]
+        assert(_type == 13)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.mpls_label = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.mpls_label != other.mpls_label: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_mpls_label {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("mpls_label = ");
+                q.text("%#x" % self.mpls_label)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[13] = set_mpls_label
+
+class set_mpls_tc(action):
+    type = 14
+
+    def __init__(self, mpls_tc=None):
+        if mpls_tc != None:
+            self.mpls_tc = mpls_tc
+        else:
+            self.mpls_tc = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!B", self.mpls_tc))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_mpls_tc()
+        _type = reader.read("!H")[0]
+        assert(_type == 14)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.mpls_tc = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.mpls_tc != other.mpls_tc: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_mpls_tc {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("mpls_tc = ");
+                q.text("%#x" % self.mpls_tc)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[14] = set_mpls_tc
+
+class set_mpls_ttl(action):
+    type = 15
+
+    def __init__(self, mpls_ttl=None):
+        if mpls_ttl != None:
+            self.mpls_ttl = mpls_ttl
+        else:
+            self.mpls_ttl = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!B", self.mpls_ttl))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_mpls_ttl()
+        _type = reader.read("!H")[0]
+        assert(_type == 15)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.mpls_ttl = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.mpls_ttl != other.mpls_ttl: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_mpls_ttl {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("mpls_ttl = ");
+                q.text("%#x" % self.mpls_ttl)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[15] = set_mpls_ttl
+
+class set_nw_dst(action):
+    type = 6
+
+    def __init__(self, nw_addr=None):
+        if nw_addr != None:
+            self.nw_addr = nw_addr
+        else:
+            self.nw_addr = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.nw_addr))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_nw_dst()
+        _type = reader.read("!H")[0]
+        assert(_type == 6)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.nw_addr = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.nw_addr != other.nw_addr: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_nw_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("nw_addr = ");
+                q.text("%#x" % self.nw_addr)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[6] = set_nw_dst
+
+class set_nw_ecn(action):
+    type = 8
+
+    def __init__(self, nw_ecn=None):
+        if nw_ecn != None:
+            self.nw_ecn = nw_ecn
+        else:
+            self.nw_ecn = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!B", self.nw_ecn))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_nw_ecn()
+        _type = reader.read("!H")[0]
+        assert(_type == 8)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.nw_ecn = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.nw_ecn != other.nw_ecn: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_nw_ecn {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("nw_ecn = ");
+                q.text("%#x" % self.nw_ecn)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[8] = set_nw_ecn
+
+class set_nw_src(action):
+    type = 5
+
+    def __init__(self, nw_addr=None):
+        if nw_addr != None:
+            self.nw_addr = nw_addr
+        else:
+            self.nw_addr = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.nw_addr))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_nw_src()
+        _type = reader.read("!H")[0]
+        assert(_type == 5)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.nw_addr = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.nw_addr != other.nw_addr: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_nw_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("nw_addr = ");
+                q.text("%#x" % self.nw_addr)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[5] = set_nw_src
+
+class set_nw_tos(action):
+    type = 7
+
+    def __init__(self, nw_tos=None):
+        if nw_tos != None:
+            self.nw_tos = nw_tos
+        else:
+            self.nw_tos = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!B", self.nw_tos))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_nw_tos()
+        _type = reader.read("!H")[0]
+        assert(_type == 7)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.nw_tos = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.nw_tos != other.nw_tos: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_nw_tos {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("nw_tos = ");
+                q.text("%#x" % self.nw_tos)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[7] = set_nw_tos
+
+class set_nw_ttl(action):
+    type = 23
+
+    def __init__(self, nw_ttl=None):
+        if nw_ttl != None:
+            self.nw_ttl = nw_ttl
+        else:
+            self.nw_ttl = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!B", self.nw_ttl))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_nw_ttl()
+        _type = reader.read("!H")[0]
+        assert(_type == 23)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.nw_ttl = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.nw_ttl != other.nw_ttl: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_nw_ttl {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("nw_ttl = ");
+                q.text("%#x" % self.nw_ttl)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[23] = set_nw_ttl
+
+class set_queue(action):
+    type = 21
+
+    def __init__(self, queue_id=None):
+        if queue_id != None:
+            self.queue_id = queue_id
+        else:
+            self.queue_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.queue_id))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_queue()
+        _type = reader.read("!H")[0]
+        assert(_type == 21)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.queue_id = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.queue_id != other.queue_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_queue {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("queue_id = ");
+                q.text("%#x" % self.queue_id)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[21] = set_queue
+
+class set_tp_dst(action):
+    type = 10
+
+    def __init__(self, tp_port=None):
+        if tp_port != None:
+            self.tp_port = tp_port
+        else:
+            self.tp_port = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!H", self.tp_port))
+        packed.append('\x00' * 2)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_tp_dst()
+        _type = reader.read("!H")[0]
+        assert(_type == 10)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.tp_port = reader.read("!H")[0]
+        reader.skip(2)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.tp_port != other.tp_port: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_tp_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("tp_port = ");
+                q.text("%#x" % self.tp_port)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[10] = set_tp_dst
+
+class set_tp_src(action):
+    type = 9
+
+    def __init__(self, tp_port=None):
+        if tp_port != None:
+            self.tp_port = tp_port
+        else:
+            self.tp_port = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!H", self.tp_port))
+        packed.append('\x00' * 2)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_tp_src()
+        _type = reader.read("!H")[0]
+        assert(_type == 9)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.tp_port = reader.read("!H")[0]
+        reader.skip(2)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.tp_port != other.tp_port: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_tp_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("tp_port = ");
+                q.text("%#x" % self.tp_port)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[9] = set_tp_src
+
+class set_vlan_pcp(action):
+    type = 2
+
+    def __init__(self, vlan_pcp=None):
+        if vlan_pcp != None:
+            self.vlan_pcp = vlan_pcp
+        else:
+            self.vlan_pcp = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!B", self.vlan_pcp))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_vlan_pcp()
+        _type = reader.read("!H")[0]
+        assert(_type == 2)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.vlan_pcp = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.vlan_pcp != other.vlan_pcp: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_vlan_pcp {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("vlan_pcp = ");
+                q.text("%#x" % self.vlan_pcp)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[2] = set_vlan_pcp
+
+class set_vlan_vid(action):
+    type = 1
+
+    def __init__(self, vlan_vid=None):
+        if vlan_vid != None:
+            self.vlan_vid = vlan_vid
+        else:
+            self.vlan_vid = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!H", self.vlan_vid))
+        packed.append('\x00' * 2)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_vlan_vid()
+        _type = reader.read("!H")[0]
+        assert(_type == 1)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.vlan_vid = reader.read("!H")[0]
+        reader.skip(2)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.vlan_vid != other.vlan_vid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_vlan_vid {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("vlan_vid = ");
+                q.text("%#x" % self.vlan_vid)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[1] = set_vlan_vid
+
+
diff --git a/Fabric/Utilities/src/python/loxi/of11/common.py b/Fabric/Utilities/src/python/loxi/of11/common.py
new file mode 100644
index 0000000..2ca0cba
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of11/common.py
@@ -0,0 +1,1747 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of11']
+
+class bsn_interface(loxi.OFObject):
+
+    def __init__(self, hw_addr=None, name=None, ipv4_addr=None, ipv4_netmask=None):
+        if hw_addr != None:
+            self.hw_addr = hw_addr
+        else:
+            self.hw_addr = [0,0,0,0,0,0]
+        if name != None:
+            self.name = name
+        else:
+            self.name = ""
+        if ipv4_addr != None:
+            self.ipv4_addr = ipv4_addr
+        else:
+            self.ipv4_addr = 0
+        if ipv4_netmask != None:
+            self.ipv4_netmask = ipv4_netmask
+        else:
+            self.ipv4_netmask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!6B", *self.hw_addr))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!16s", self.name))
+        packed.append(struct.pack("!L", self.ipv4_addr))
+        packed.append(struct.pack("!L", self.ipv4_netmask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_interface()
+        obj.hw_addr = list(reader.read('!6B'))
+        reader.skip(2)
+        obj.name = reader.read("!16s")[0].rstrip("\x00")
+        obj.ipv4_addr = reader.read("!L")[0]
+        obj.ipv4_netmask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.hw_addr != other.hw_addr: return False
+        if self.name != other.name: return False
+        if self.ipv4_addr != other.ipv4_addr: return False
+        if self.ipv4_netmask != other.ipv4_netmask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_interface {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("hw_addr = ");
+                q.text(util.pretty_mac(self.hw_addr))
+                q.text(","); q.breakable()
+                q.text("name = ");
+                q.pp(self.name)
+                q.text(","); q.breakable()
+                q.text("ipv4_addr = ");
+                q.text(util.pretty_ipv4(self.ipv4_addr))
+                q.text(","); q.breakable()
+                q.text("ipv4_netmask = ");
+                q.text(util.pretty_ipv4(self.ipv4_netmask))
+            q.breakable()
+        q.text('}')
+
+
+class bsn_vport(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = bsn_vport.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = bsn_vport()
+        obj.type = reader.read("!H")[0]
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vport {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class bsn_vport_l2gre(bsn_vport):
+    type = 1
+
+    def __init__(self, flags=None, port_no=None, loopback_port_no=None, local_mac=None, nh_mac=None, src_ip=None, dst_ip=None, dscp=None, ttl=None, vpn=None, rate_limit=None, if_name=None):
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if loopback_port_no != None:
+            self.loopback_port_no = loopback_port_no
+        else:
+            self.loopback_port_no = 0
+        if local_mac != None:
+            self.local_mac = local_mac
+        else:
+            self.local_mac = [0,0,0,0,0,0]
+        if nh_mac != None:
+            self.nh_mac = nh_mac
+        else:
+            self.nh_mac = [0,0,0,0,0,0]
+        if src_ip != None:
+            self.src_ip = src_ip
+        else:
+            self.src_ip = 0
+        if dst_ip != None:
+            self.dst_ip = dst_ip
+        else:
+            self.dst_ip = 0
+        if dscp != None:
+            self.dscp = dscp
+        else:
+            self.dscp = 0
+        if ttl != None:
+            self.ttl = ttl
+        else:
+            self.ttl = 0
+        if vpn != None:
+            self.vpn = vpn
+        else:
+            self.vpn = 0
+        if rate_limit != None:
+            self.rate_limit = rate_limit
+        else:
+            self.rate_limit = 0
+        if if_name != None:
+            self.if_name = if_name
+        else:
+            self.if_name = ""
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.flags))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(util.pack_port_no(self.loopback_port_no))
+        packed.append(struct.pack("!6B", *self.local_mac))
+        packed.append(struct.pack("!6B", *self.nh_mac))
+        packed.append(struct.pack("!L", self.src_ip))
+        packed.append(struct.pack("!L", self.dst_ip))
+        packed.append(struct.pack("!B", self.dscp))
+        packed.append(struct.pack("!B", self.ttl))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!L", self.vpn))
+        packed.append(struct.pack("!L", self.rate_limit))
+        packed.append(struct.pack("!16s", self.if_name))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vport_l2gre()
+        _type = reader.read("!H")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.flags = reader.read("!L")[0]
+        obj.port_no = util.unpack_port_no(reader)
+        obj.loopback_port_no = util.unpack_port_no(reader)
+        obj.local_mac = list(reader.read('!6B'))
+        obj.nh_mac = list(reader.read('!6B'))
+        obj.src_ip = reader.read("!L")[0]
+        obj.dst_ip = reader.read("!L")[0]
+        obj.dscp = reader.read("!B")[0]
+        obj.ttl = reader.read("!B")[0]
+        reader.skip(2)
+        obj.vpn = reader.read("!L")[0]
+        obj.rate_limit = reader.read("!L")[0]
+        obj.if_name = reader.read("!16s")[0].rstrip("\x00")
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.flags != other.flags: return False
+        if self.port_no != other.port_no: return False
+        if self.loopback_port_no != other.loopback_port_no: return False
+        if self.local_mac != other.local_mac: return False
+        if self.nh_mac != other.nh_mac: return False
+        if self.src_ip != other.src_ip: return False
+        if self.dst_ip != other.dst_ip: return False
+        if self.dscp != other.dscp: return False
+        if self.ttl != other.ttl: return False
+        if self.vpn != other.vpn: return False
+        if self.rate_limit != other.rate_limit: return False
+        if self.if_name != other.if_name: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vport_l2gre {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("loopback_port_no = ");
+                q.text(util.pretty_port(self.loopback_port_no))
+                q.text(","); q.breakable()
+                q.text("local_mac = ");
+                q.text(util.pretty_mac(self.local_mac))
+                q.text(","); q.breakable()
+                q.text("nh_mac = ");
+                q.text(util.pretty_mac(self.nh_mac))
+                q.text(","); q.breakable()
+                q.text("src_ip = ");
+                q.text(util.pretty_ipv4(self.src_ip))
+                q.text(","); q.breakable()
+                q.text("dst_ip = ");
+                q.text(util.pretty_ipv4(self.dst_ip))
+                q.text(","); q.breakable()
+                q.text("dscp = ");
+                q.text("%#x" % self.dscp)
+                q.text(","); q.breakable()
+                q.text("ttl = ");
+                q.text("%#x" % self.ttl)
+                q.text(","); q.breakable()
+                q.text("vpn = ");
+                q.text("%#x" % self.vpn)
+                q.text(","); q.breakable()
+                q.text("rate_limit = ");
+                q.text("%#x" % self.rate_limit)
+                q.text(","); q.breakable()
+                q.text("if_name = ");
+                q.pp(self.if_name)
+            q.breakable()
+        q.text('}')
+
+bsn_vport.subtypes[1] = bsn_vport_l2gre
+
+class bsn_vport_q_in_q(bsn_vport):
+    type = 0
+
+    def __init__(self, port_no=None, ingress_tpid=None, ingress_vlan_id=None, egress_tpid=None, egress_vlan_id=None, if_name=None):
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if ingress_tpid != None:
+            self.ingress_tpid = ingress_tpid
+        else:
+            self.ingress_tpid = 0
+        if ingress_vlan_id != None:
+            self.ingress_vlan_id = ingress_vlan_id
+        else:
+            self.ingress_vlan_id = 0
+        if egress_tpid != None:
+            self.egress_tpid = egress_tpid
+        else:
+            self.egress_tpid = 0
+        if egress_vlan_id != None:
+            self.egress_vlan_id = egress_vlan_id
+        else:
+            self.egress_vlan_id = 0
+        if if_name != None:
+            self.if_name = if_name
+        else:
+            self.if_name = ""
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.port_no))
+        packed.append(struct.pack("!H", self.ingress_tpid))
+        packed.append(struct.pack("!H", self.ingress_vlan_id))
+        packed.append(struct.pack("!H", self.egress_tpid))
+        packed.append(struct.pack("!H", self.egress_vlan_id))
+        packed.append(struct.pack("!16s", self.if_name))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vport_q_in_q()
+        _type = reader.read("!H")[0]
+        assert(_type == 0)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.port_no = reader.read("!L")[0]
+        obj.ingress_tpid = reader.read("!H")[0]
+        obj.ingress_vlan_id = reader.read("!H")[0]
+        obj.egress_tpid = reader.read("!H")[0]
+        obj.egress_vlan_id = reader.read("!H")[0]
+        obj.if_name = reader.read("!16s")[0].rstrip("\x00")
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.port_no != other.port_no: return False
+        if self.ingress_tpid != other.ingress_tpid: return False
+        if self.ingress_vlan_id != other.ingress_vlan_id: return False
+        if self.egress_tpid != other.egress_tpid: return False
+        if self.egress_vlan_id != other.egress_vlan_id: return False
+        if self.if_name != other.if_name: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vport_q_in_q {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("port_no = ");
+                q.text("%#x" % self.port_no)
+                q.text(","); q.breakable()
+                q.text("ingress_tpid = ");
+                q.text("%#x" % self.ingress_tpid)
+                q.text(","); q.breakable()
+                q.text("ingress_vlan_id = ");
+                q.text("%#x" % self.ingress_vlan_id)
+                q.text(","); q.breakable()
+                q.text("egress_tpid = ");
+                q.text("%#x" % self.egress_tpid)
+                q.text(","); q.breakable()
+                q.text("egress_vlan_id = ");
+                q.text("%#x" % self.egress_vlan_id)
+                q.text(","); q.breakable()
+                q.text("if_name = ");
+                q.pp(self.if_name)
+            q.breakable()
+        q.text('}')
+
+bsn_vport.subtypes[0] = bsn_vport_q_in_q
+
+class bucket(loxi.OFObject):
+
+    def __init__(self, weight=None, watch_port=None, watch_group=None, actions=None):
+        if weight != None:
+            self.weight = weight
+        else:
+            self.weight = 0
+        if watch_port != None:
+            self.watch_port = watch_port
+        else:
+            self.watch_port = 0
+        if watch_group != None:
+            self.watch_group = watch_group
+        else:
+            self.watch_group = 0
+        if actions != None:
+            self.actions = actions
+        else:
+            self.actions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 0
+        packed.append(struct.pack("!H", self.weight))
+        packed.append(util.pack_port_no(self.watch_port))
+        packed.append(struct.pack("!L", self.watch_group))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.actions))
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bucket()
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 2)
+        obj.weight = reader.read("!H")[0]
+        obj.watch_port = util.unpack_port_no(reader)
+        obj.watch_group = reader.read("!L")[0]
+        reader.skip(4)
+        obj.actions = loxi.generic_util.unpack_list(reader, ofp.action.action.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.weight != other.weight: return False
+        if self.watch_port != other.watch_port: return False
+        if self.watch_group != other.watch_group: return False
+        if self.actions != other.actions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bucket {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("weight = ");
+                q.text("%#x" % self.weight)
+                q.text(","); q.breakable()
+                q.text("watch_port = ");
+                q.text(util.pretty_port(self.watch_port))
+                q.text(","); q.breakable()
+                q.text("watch_group = ");
+                q.text("%#x" % self.watch_group)
+                q.text(","); q.breakable()
+                q.text("actions = ");
+                q.pp(self.actions)
+            q.breakable()
+        q.text('}')
+
+
+class bucket_counter(loxi.OFObject):
+
+    def __init__(self, packet_count=None, byte_count=None):
+        if packet_count != None:
+            self.packet_count = packet_count
+        else:
+            self.packet_count = 0
+        if byte_count != None:
+            self.byte_count = byte_count
+        else:
+            self.byte_count = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!Q", self.packet_count))
+        packed.append(struct.pack("!Q", self.byte_count))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bucket_counter()
+        obj.packet_count = reader.read("!Q")[0]
+        obj.byte_count = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.packet_count != other.packet_count: return False
+        if self.byte_count != other.byte_count: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bucket_counter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("packet_count = ");
+                q.text("%#x" % self.packet_count)
+                q.text(","); q.breakable()
+                q.text("byte_count = ");
+                q.text("%#x" % self.byte_count)
+            q.breakable()
+        q.text('}')
+
+
+class flow_stats_entry(loxi.OFObject):
+
+    def __init__(self, table_id=None, duration_sec=None, duration_nsec=None, priority=None, idle_timeout=None, hard_timeout=None, cookie=None, packet_count=None, byte_count=None, match=None, instructions=None):
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if duration_sec != None:
+            self.duration_sec = duration_sec
+        else:
+            self.duration_sec = 0
+        if duration_nsec != None:
+            self.duration_nsec = duration_nsec
+        else:
+            self.duration_nsec = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if packet_count != None:
+            self.packet_count = packet_count
+        else:
+            self.packet_count = 0
+        if byte_count != None:
+            self.byte_count = byte_count
+        else:
+            self.byte_count = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if instructions != None:
+            self.instructions = instructions
+        else:
+            self.instructions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 0
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!L", self.duration_sec))
+        packed.append(struct.pack("!L", self.duration_nsec))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append('\x00' * 6)
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.packet_count))
+        packed.append(struct.pack("!Q", self.byte_count))
+        packed.append(self.match.pack())
+        packed.append(loxi.generic_util.pack_list(self.instructions))
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_stats_entry()
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 2)
+        obj.table_id = reader.read("!B")[0]
+        reader.skip(1)
+        obj.duration_sec = reader.read("!L")[0]
+        obj.duration_nsec = reader.read("!L")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        reader.skip(6)
+        obj.cookie = reader.read("!Q")[0]
+        obj.packet_count = reader.read("!Q")[0]
+        obj.byte_count = reader.read("!Q")[0]
+        obj.match = ofp.match.unpack(reader)
+        obj.instructions = loxi.generic_util.unpack_list(reader, ofp.instruction.instruction.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.table_id != other.table_id: return False
+        if self.duration_sec != other.duration_sec: return False
+        if self.duration_nsec != other.duration_nsec: return False
+        if self.priority != other.priority: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.cookie != other.cookie: return False
+        if self.packet_count != other.packet_count: return False
+        if self.byte_count != other.byte_count: return False
+        if self.match != other.match: return False
+        if self.instructions != other.instructions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("duration_sec = ");
+                q.text("%#x" % self.duration_sec)
+                q.text(","); q.breakable()
+                q.text("duration_nsec = ");
+                q.text("%#x" % self.duration_nsec)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("packet_count = ");
+                q.text("%#x" % self.packet_count)
+                q.text(","); q.breakable()
+                q.text("byte_count = ");
+                q.text("%#x" % self.byte_count)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("instructions = ");
+                q.pp(self.instructions)
+            q.breakable()
+        q.text('}')
+
+
+class group_desc_stats_entry(loxi.OFObject):
+
+    def __init__(self, group_type=None, group_id=None, buckets=None):
+        if group_type != None:
+            self.group_type = group_type
+        else:
+            self.group_type = 0
+        if group_id != None:
+            self.group_id = group_id
+        else:
+            self.group_id = 0
+        if buckets != None:
+            self.buckets = buckets
+        else:
+            self.buckets = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 0
+        packed.append(struct.pack("!B", self.group_type))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!L", self.group_id))
+        packed.append(loxi.generic_util.pack_list(self.buckets))
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_desc_stats_entry()
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 2)
+        obj.group_type = reader.read("!B")[0]
+        reader.skip(1)
+        obj.group_id = reader.read("!L")[0]
+        obj.buckets = loxi.generic_util.unpack_list(reader, ofp.common.bucket.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.group_type != other.group_type: return False
+        if self.group_id != other.group_id: return False
+        if self.buckets != other.buckets: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_desc_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("group_type = ");
+                q.text("%#x" % self.group_type)
+                q.text(","); q.breakable()
+                q.text("group_id = ");
+                q.text("%#x" % self.group_id)
+                q.text(","); q.breakable()
+                q.text("buckets = ");
+                q.pp(self.buckets)
+            q.breakable()
+        q.text('}')
+
+
+class group_stats_entry(loxi.OFObject):
+
+    def __init__(self, group_id=None, ref_count=None, packet_count=None, byte_count=None, bucket_stats=None):
+        if group_id != None:
+            self.group_id = group_id
+        else:
+            self.group_id = 0
+        if ref_count != None:
+            self.ref_count = ref_count
+        else:
+            self.ref_count = 0
+        if packet_count != None:
+            self.packet_count = packet_count
+        else:
+            self.packet_count = 0
+        if byte_count != None:
+            self.byte_count = byte_count
+        else:
+            self.byte_count = 0
+        if bucket_stats != None:
+            self.bucket_stats = bucket_stats
+        else:
+            self.bucket_stats = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 0
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!L", self.group_id))
+        packed.append(struct.pack("!L", self.ref_count))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!Q", self.packet_count))
+        packed.append(struct.pack("!Q", self.byte_count))
+        packed.append(loxi.generic_util.pack_list(self.bucket_stats))
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_stats_entry()
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 2)
+        reader.skip(2)
+        obj.group_id = reader.read("!L")[0]
+        obj.ref_count = reader.read("!L")[0]
+        reader.skip(4)
+        obj.packet_count = reader.read("!Q")[0]
+        obj.byte_count = reader.read("!Q")[0]
+        obj.bucket_stats = loxi.generic_util.unpack_list(reader, ofp.common.bucket_counter.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.group_id != other.group_id: return False
+        if self.ref_count != other.ref_count: return False
+        if self.packet_count != other.packet_count: return False
+        if self.byte_count != other.byte_count: return False
+        if self.bucket_stats != other.bucket_stats: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("group_id = ");
+                q.text("%#x" % self.group_id)
+                q.text(","); q.breakable()
+                q.text("ref_count = ");
+                q.text("%#x" % self.ref_count)
+                q.text(","); q.breakable()
+                q.text("packet_count = ");
+                q.text("%#x" % self.packet_count)
+                q.text(","); q.breakable()
+                q.text("byte_count = ");
+                q.text("%#x" % self.byte_count)
+                q.text(","); q.breakable()
+                q.text("bucket_stats = ");
+                q.pp(self.bucket_stats)
+            q.breakable()
+        q.text('}')
+
+
+class match_v2(loxi.OFObject):
+    type = 0
+
+    def __init__(self, in_port=None, wildcards=None, eth_src=None, eth_src_mask=None, eth_dst=None, eth_dst_mask=None, vlan_vid=None, vlan_pcp=None, eth_type=None, ip_dscp=None, ip_proto=None, ipv4_src=None, ipv4_src_mask=None, ipv4_dst=None, ipv4_dst_mask=None, tcp_src=None, tcp_dst=None, mpls_label=None, mpls_tc=None, metadata=None, metadata_mask=None):
+        if in_port != None:
+            self.in_port = in_port
+        else:
+            self.in_port = 0
+        if wildcards != None:
+            self.wildcards = wildcards
+        else:
+            self.wildcards = util.init_wc_bmap()
+        if eth_src != None:
+            self.eth_src = eth_src
+        else:
+            self.eth_src = [0,0,0,0,0,0]
+        if eth_src_mask != None:
+            self.eth_src_mask = eth_src_mask
+        else:
+            self.eth_src_mask = [0,0,0,0,0,0]
+        if eth_dst != None:
+            self.eth_dst = eth_dst
+        else:
+            self.eth_dst = [0,0,0,0,0,0]
+        if eth_dst_mask != None:
+            self.eth_dst_mask = eth_dst_mask
+        else:
+            self.eth_dst_mask = [0,0,0,0,0,0]
+        if vlan_vid != None:
+            self.vlan_vid = vlan_vid
+        else:
+            self.vlan_vid = 0
+        if vlan_pcp != None:
+            self.vlan_pcp = vlan_pcp
+        else:
+            self.vlan_pcp = 0
+        if eth_type != None:
+            self.eth_type = eth_type
+        else:
+            self.eth_type = 0
+        if ip_dscp != None:
+            self.ip_dscp = ip_dscp
+        else:
+            self.ip_dscp = 0
+        if ip_proto != None:
+            self.ip_proto = ip_proto
+        else:
+            self.ip_proto = 0
+        if ipv4_src != None:
+            self.ipv4_src = ipv4_src
+        else:
+            self.ipv4_src = 0
+        if ipv4_src_mask != None:
+            self.ipv4_src_mask = ipv4_src_mask
+        else:
+            self.ipv4_src_mask = 0
+        if ipv4_dst != None:
+            self.ipv4_dst = ipv4_dst
+        else:
+            self.ipv4_dst = 0
+        if ipv4_dst_mask != None:
+            self.ipv4_dst_mask = ipv4_dst_mask
+        else:
+            self.ipv4_dst_mask = 0
+        if tcp_src != None:
+            self.tcp_src = tcp_src
+        else:
+            self.tcp_src = 0
+        if tcp_dst != None:
+            self.tcp_dst = tcp_dst
+        else:
+            self.tcp_dst = 0
+        if mpls_label != None:
+            self.mpls_label = mpls_label
+        else:
+            self.mpls_label = 0
+        if mpls_tc != None:
+            self.mpls_tc = mpls_tc
+        else:
+            self.mpls_tc = 0
+        if metadata != None:
+            self.metadata = metadata
+        else:
+            self.metadata = 0
+        if metadata_mask != None:
+            self.metadata_mask = metadata_mask
+        else:
+            self.metadata_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(util.pack_port_no(self.in_port))
+        packed.append(util.pack_wc_bmap(self.wildcards))
+        packed.append(struct.pack("!6B", *self.eth_src))
+        packed.append(struct.pack("!6B", *self.eth_src_mask))
+        packed.append(struct.pack("!6B", *self.eth_dst))
+        packed.append(struct.pack("!6B", *self.eth_dst_mask))
+        packed.append(struct.pack("!H", self.vlan_vid))
+        packed.append(struct.pack("!B", self.vlan_pcp))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!H", self.eth_type))
+        packed.append(struct.pack("!B", self.ip_dscp))
+        packed.append(struct.pack("!B", self.ip_proto))
+        packed.append(struct.pack("!L", self.ipv4_src))
+        packed.append(struct.pack("!L", self.ipv4_src_mask))
+        packed.append(struct.pack("!L", self.ipv4_dst))
+        packed.append(struct.pack("!L", self.ipv4_dst_mask))
+        packed.append(struct.pack("!H", self.tcp_src))
+        packed.append(struct.pack("!H", self.tcp_dst))
+        packed.append(struct.pack("!L", self.mpls_label))
+        packed.append(struct.pack("!B", self.mpls_tc))
+        packed.append('\x00' * 3)
+        packed.append(struct.pack("!Q", self.metadata))
+        packed.append(struct.pack("!Q", self.metadata_mask))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = match_v2()
+        _type = reader.read("!H")[0]
+        assert(_type == 0)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.in_port = util.unpack_port_no(reader)
+        obj.wildcards = util.unpack_wc_bmap(reader)
+        obj.eth_src = list(reader.read('!6B'))
+        obj.eth_src_mask = list(reader.read('!6B'))
+        obj.eth_dst = list(reader.read('!6B'))
+        obj.eth_dst_mask = list(reader.read('!6B'))
+        obj.vlan_vid = reader.read("!H")[0]
+        obj.vlan_pcp = reader.read("!B")[0]
+        reader.skip(1)
+        obj.eth_type = reader.read("!H")[0]
+        obj.ip_dscp = reader.read("!B")[0]
+        obj.ip_proto = reader.read("!B")[0]
+        obj.ipv4_src = reader.read("!L")[0]
+        obj.ipv4_src_mask = reader.read("!L")[0]
+        obj.ipv4_dst = reader.read("!L")[0]
+        obj.ipv4_dst_mask = reader.read("!L")[0]
+        obj.tcp_src = reader.read("!H")[0]
+        obj.tcp_dst = reader.read("!H")[0]
+        obj.mpls_label = reader.read("!L")[0]
+        obj.mpls_tc = reader.read("!B")[0]
+        reader.skip(3)
+        obj.metadata = reader.read("!Q")[0]
+        obj.metadata_mask = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.in_port != other.in_port: return False
+        if self.wildcards != other.wildcards: return False
+        if self.eth_src != other.eth_src: return False
+        if self.eth_src_mask != other.eth_src_mask: return False
+        if self.eth_dst != other.eth_dst: return False
+        if self.eth_dst_mask != other.eth_dst_mask: return False
+        if self.vlan_vid != other.vlan_vid: return False
+        if self.vlan_pcp != other.vlan_pcp: return False
+        if self.eth_type != other.eth_type: return False
+        if self.ip_dscp != other.ip_dscp: return False
+        if self.ip_proto != other.ip_proto: return False
+        if self.ipv4_src != other.ipv4_src: return False
+        if self.ipv4_src_mask != other.ipv4_src_mask: return False
+        if self.ipv4_dst != other.ipv4_dst: return False
+        if self.ipv4_dst_mask != other.ipv4_dst_mask: return False
+        if self.tcp_src != other.tcp_src: return False
+        if self.tcp_dst != other.tcp_dst: return False
+        if self.mpls_label != other.mpls_label: return False
+        if self.mpls_tc != other.mpls_tc: return False
+        if self.metadata != other.metadata: return False
+        if self.metadata_mask != other.metadata_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("match_v2 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("in_port = ");
+                q.text(util.pretty_port(self.in_port))
+                q.text(","); q.breakable()
+                q.text("wildcards = ");
+                q.text(util.pretty_wildcards(self.wildcards))
+                q.text(","); q.breakable()
+                q.text("eth_src = ");
+                q.text(util.pretty_mac(self.eth_src))
+                q.text(","); q.breakable()
+                q.text("eth_src_mask = ");
+                q.text(util.pretty_mac(self.eth_src_mask))
+                q.text(","); q.breakable()
+                q.text("eth_dst = ");
+                q.text(util.pretty_mac(self.eth_dst))
+                q.text(","); q.breakable()
+                q.text("eth_dst_mask = ");
+                q.text(util.pretty_mac(self.eth_dst_mask))
+                q.text(","); q.breakable()
+                q.text("vlan_vid = ");
+                q.text("%#x" % self.vlan_vid)
+                q.text(","); q.breakable()
+                q.text("vlan_pcp = ");
+                q.text("%#x" % self.vlan_pcp)
+                q.text(","); q.breakable()
+                q.text("eth_type = ");
+                q.text("%#x" % self.eth_type)
+                q.text(","); q.breakable()
+                q.text("ip_dscp = ");
+                q.text("%#x" % self.ip_dscp)
+                q.text(","); q.breakable()
+                q.text("ip_proto = ");
+                q.text("%#x" % self.ip_proto)
+                q.text(","); q.breakable()
+                q.text("ipv4_src = ");
+                q.text(util.pretty_ipv4(self.ipv4_src))
+                q.text(","); q.breakable()
+                q.text("ipv4_src_mask = ");
+                q.text(util.pretty_ipv4(self.ipv4_src_mask))
+                q.text(","); q.breakable()
+                q.text("ipv4_dst = ");
+                q.text(util.pretty_ipv4(self.ipv4_dst))
+                q.text(","); q.breakable()
+                q.text("ipv4_dst_mask = ");
+                q.text(util.pretty_ipv4(self.ipv4_dst_mask))
+                q.text(","); q.breakable()
+                q.text("tcp_src = ");
+                q.text("%#x" % self.tcp_src)
+                q.text(","); q.breakable()
+                q.text("tcp_dst = ");
+                q.text("%#x" % self.tcp_dst)
+                q.text(","); q.breakable()
+                q.text("mpls_label = ");
+                q.text("%#x" % self.mpls_label)
+                q.text(","); q.breakable()
+                q.text("mpls_tc = ");
+                q.text("%#x" % self.mpls_tc)
+                q.text(","); q.breakable()
+                q.text("metadata = ");
+                q.text("%#x" % self.metadata)
+                q.text(","); q.breakable()
+                q.text("metadata_mask = ");
+                q.text("%#x" % self.metadata_mask)
+            q.breakable()
+        q.text('}')
+
+
+class packet_queue(loxi.OFObject):
+
+    def __init__(self, queue_id=None, properties=None):
+        if queue_id != None:
+            self.queue_id = queue_id
+        else:
+            self.queue_id = 0
+        if properties != None:
+            self.properties = properties
+        else:
+            self.properties = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.queue_id))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 2)
+        packed.append(loxi.generic_util.pack_list(self.properties))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = packet_queue()
+        obj.queue_id = reader.read("!L")[0]
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 6)
+        reader.skip(2)
+        obj.properties = loxi.generic_util.unpack_list(reader, ofp.common.queue_prop.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.queue_id != other.queue_id: return False
+        if self.properties != other.properties: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("packet_queue {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("queue_id = ");
+                q.text("%#x" % self.queue_id)
+                q.text(","); q.breakable()
+                q.text("properties = ");
+                q.pp(self.properties)
+            q.breakable()
+        q.text('}')
+
+
+class port_desc(loxi.OFObject):
+
+    def __init__(self, port_no=None, hw_addr=None, name=None, config=None, state=None, curr=None, advertised=None, supported=None, peer=None, curr_speed=None, max_speed=None):
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if hw_addr != None:
+            self.hw_addr = hw_addr
+        else:
+            self.hw_addr = [0,0,0,0,0,0]
+        if name != None:
+            self.name = name
+        else:
+            self.name = ""
+        if config != None:
+            self.config = config
+        else:
+            self.config = 0
+        if state != None:
+            self.state = state
+        else:
+            self.state = 0
+        if curr != None:
+            self.curr = curr
+        else:
+            self.curr = 0
+        if advertised != None:
+            self.advertised = advertised
+        else:
+            self.advertised = 0
+        if supported != None:
+            self.supported = supported
+        else:
+            self.supported = 0
+        if peer != None:
+            self.peer = peer
+        else:
+            self.peer = 0
+        if curr_speed != None:
+            self.curr_speed = curr_speed
+        else:
+            self.curr_speed = 0
+        if max_speed != None:
+            self.max_speed = max_speed
+        else:
+            self.max_speed = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!6B", *self.hw_addr))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!16s", self.name))
+        packed.append(struct.pack("!L", self.config))
+        packed.append(struct.pack("!L", self.state))
+        packed.append(struct.pack("!L", self.curr))
+        packed.append(struct.pack("!L", self.advertised))
+        packed.append(struct.pack("!L", self.supported))
+        packed.append(struct.pack("!L", self.peer))
+        packed.append(struct.pack("!L", self.curr_speed))
+        packed.append(struct.pack("!L", self.max_speed))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_desc()
+        obj.port_no = util.unpack_port_no(reader)
+        reader.skip(4)
+        obj.hw_addr = list(reader.read('!6B'))
+        reader.skip(2)
+        obj.name = reader.read("!16s")[0].rstrip("\x00")
+        obj.config = reader.read("!L")[0]
+        obj.state = reader.read("!L")[0]
+        obj.curr = reader.read("!L")[0]
+        obj.advertised = reader.read("!L")[0]
+        obj.supported = reader.read("!L")[0]
+        obj.peer = reader.read("!L")[0]
+        obj.curr_speed = reader.read("!L")[0]
+        obj.max_speed = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.port_no != other.port_no: return False
+        if self.hw_addr != other.hw_addr: return False
+        if self.name != other.name: return False
+        if self.config != other.config: return False
+        if self.state != other.state: return False
+        if self.curr != other.curr: return False
+        if self.advertised != other.advertised: return False
+        if self.supported != other.supported: return False
+        if self.peer != other.peer: return False
+        if self.curr_speed != other.curr_speed: return False
+        if self.max_speed != other.max_speed: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_desc {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("hw_addr = ");
+                q.text(util.pretty_mac(self.hw_addr))
+                q.text(","); q.breakable()
+                q.text("name = ");
+                q.pp(self.name)
+                q.text(","); q.breakable()
+                q.text("config = ");
+                q.text("%#x" % self.config)
+                q.text(","); q.breakable()
+                q.text("state = ");
+                q.text("%#x" % self.state)
+                q.text(","); q.breakable()
+                q.text("curr = ");
+                q.text("%#x" % self.curr)
+                q.text(","); q.breakable()
+                q.text("advertised = ");
+                q.text("%#x" % self.advertised)
+                q.text(","); q.breakable()
+                q.text("supported = ");
+                q.text("%#x" % self.supported)
+                q.text(","); q.breakable()
+                q.text("peer = ");
+                q.text("%#x" % self.peer)
+                q.text(","); q.breakable()
+                q.text("curr_speed = ");
+                q.text("%#x" % self.curr_speed)
+                q.text(","); q.breakable()
+                q.text("max_speed = ");
+                q.text("%#x" % self.max_speed)
+            q.breakable()
+        q.text('}')
+
+
+class port_stats_entry(loxi.OFObject):
+
+    def __init__(self, port_no=None, rx_packets=None, tx_packets=None, rx_bytes=None, tx_bytes=None, rx_dropped=None, tx_dropped=None, rx_errors=None, tx_errors=None, rx_frame_err=None, rx_over_err=None, rx_crc_err=None, collisions=None):
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if rx_packets != None:
+            self.rx_packets = rx_packets
+        else:
+            self.rx_packets = 0
+        if tx_packets != None:
+            self.tx_packets = tx_packets
+        else:
+            self.tx_packets = 0
+        if rx_bytes != None:
+            self.rx_bytes = rx_bytes
+        else:
+            self.rx_bytes = 0
+        if tx_bytes != None:
+            self.tx_bytes = tx_bytes
+        else:
+            self.tx_bytes = 0
+        if rx_dropped != None:
+            self.rx_dropped = rx_dropped
+        else:
+            self.rx_dropped = 0
+        if tx_dropped != None:
+            self.tx_dropped = tx_dropped
+        else:
+            self.tx_dropped = 0
+        if rx_errors != None:
+            self.rx_errors = rx_errors
+        else:
+            self.rx_errors = 0
+        if tx_errors != None:
+            self.tx_errors = tx_errors
+        else:
+            self.tx_errors = 0
+        if rx_frame_err != None:
+            self.rx_frame_err = rx_frame_err
+        else:
+            self.rx_frame_err = 0
+        if rx_over_err != None:
+            self.rx_over_err = rx_over_err
+        else:
+            self.rx_over_err = 0
+        if rx_crc_err != None:
+            self.rx_crc_err = rx_crc_err
+        else:
+            self.rx_crc_err = 0
+        if collisions != None:
+            self.collisions = collisions
+        else:
+            self.collisions = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!Q", self.rx_packets))
+        packed.append(struct.pack("!Q", self.tx_packets))
+        packed.append(struct.pack("!Q", self.rx_bytes))
+        packed.append(struct.pack("!Q", self.tx_bytes))
+        packed.append(struct.pack("!Q", self.rx_dropped))
+        packed.append(struct.pack("!Q", self.tx_dropped))
+        packed.append(struct.pack("!Q", self.rx_errors))
+        packed.append(struct.pack("!Q", self.tx_errors))
+        packed.append(struct.pack("!Q", self.rx_frame_err))
+        packed.append(struct.pack("!Q", self.rx_over_err))
+        packed.append(struct.pack("!Q", self.rx_crc_err))
+        packed.append(struct.pack("!Q", self.collisions))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_stats_entry()
+        obj.port_no = util.unpack_port_no(reader)
+        reader.skip(4)
+        obj.rx_packets = reader.read("!Q")[0]
+        obj.tx_packets = reader.read("!Q")[0]
+        obj.rx_bytes = reader.read("!Q")[0]
+        obj.tx_bytes = reader.read("!Q")[0]
+        obj.rx_dropped = reader.read("!Q")[0]
+        obj.tx_dropped = reader.read("!Q")[0]
+        obj.rx_errors = reader.read("!Q")[0]
+        obj.tx_errors = reader.read("!Q")[0]
+        obj.rx_frame_err = reader.read("!Q")[0]
+        obj.rx_over_err = reader.read("!Q")[0]
+        obj.rx_crc_err = reader.read("!Q")[0]
+        obj.collisions = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.port_no != other.port_no: return False
+        if self.rx_packets != other.rx_packets: return False
+        if self.tx_packets != other.tx_packets: return False
+        if self.rx_bytes != other.rx_bytes: return False
+        if self.tx_bytes != other.tx_bytes: return False
+        if self.rx_dropped != other.rx_dropped: return False
+        if self.tx_dropped != other.tx_dropped: return False
+        if self.rx_errors != other.rx_errors: return False
+        if self.tx_errors != other.tx_errors: return False
+        if self.rx_frame_err != other.rx_frame_err: return False
+        if self.rx_over_err != other.rx_over_err: return False
+        if self.rx_crc_err != other.rx_crc_err: return False
+        if self.collisions != other.collisions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("rx_packets = ");
+                q.text("%#x" % self.rx_packets)
+                q.text(","); q.breakable()
+                q.text("tx_packets = ");
+                q.text("%#x" % self.tx_packets)
+                q.text(","); q.breakable()
+                q.text("rx_bytes = ");
+                q.text("%#x" % self.rx_bytes)
+                q.text(","); q.breakable()
+                q.text("tx_bytes = ");
+                q.text("%#x" % self.tx_bytes)
+                q.text(","); q.breakable()
+                q.text("rx_dropped = ");
+                q.text("%#x" % self.rx_dropped)
+                q.text(","); q.breakable()
+                q.text("tx_dropped = ");
+                q.text("%#x" % self.tx_dropped)
+                q.text(","); q.breakable()
+                q.text("rx_errors = ");
+                q.text("%#x" % self.rx_errors)
+                q.text(","); q.breakable()
+                q.text("tx_errors = ");
+                q.text("%#x" % self.tx_errors)
+                q.text(","); q.breakable()
+                q.text("rx_frame_err = ");
+                q.text("%#x" % self.rx_frame_err)
+                q.text(","); q.breakable()
+                q.text("rx_over_err = ");
+                q.text("%#x" % self.rx_over_err)
+                q.text(","); q.breakable()
+                q.text("rx_crc_err = ");
+                q.text("%#x" % self.rx_crc_err)
+                q.text(","); q.breakable()
+                q.text("collisions = ");
+                q.text("%#x" % self.collisions)
+            q.breakable()
+        q.text('}')
+
+
+class queue_prop(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = queue_prop.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = queue_prop()
+        obj.type = reader.read("!H")[0]
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_prop {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class queue_prop_min_rate(queue_prop):
+    type = 1
+
+    def __init__(self, rate=None):
+        if rate != None:
+            self.rate = rate
+        else:
+            self.rate = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!H", self.rate))
+        packed.append('\x00' * 6)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_prop_min_rate()
+        _type = reader.read("!H")[0]
+        assert(_type == 1)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        obj.rate = reader.read("!H")[0]
+        reader.skip(6)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.rate != other.rate: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_prop_min_rate {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("rate = ");
+                q.text("%#x" % self.rate)
+            q.breakable()
+        q.text('}')
+
+queue_prop.subtypes[1] = queue_prop_min_rate
+
+class queue_stats_entry(loxi.OFObject):
+
+    def __init__(self, port_no=None, queue_id=None, tx_bytes=None, tx_packets=None, tx_errors=None):
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if queue_id != None:
+            self.queue_id = queue_id
+        else:
+            self.queue_id = 0
+        if tx_bytes != None:
+            self.tx_bytes = tx_bytes
+        else:
+            self.tx_bytes = 0
+        if tx_packets != None:
+            self.tx_packets = tx_packets
+        else:
+            self.tx_packets = 0
+        if tx_errors != None:
+            self.tx_errors = tx_errors
+        else:
+            self.tx_errors = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!L", self.queue_id))
+        packed.append(struct.pack("!Q", self.tx_bytes))
+        packed.append(struct.pack("!Q", self.tx_packets))
+        packed.append(struct.pack("!Q", self.tx_errors))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_stats_entry()
+        obj.port_no = util.unpack_port_no(reader)
+        obj.queue_id = reader.read("!L")[0]
+        obj.tx_bytes = reader.read("!Q")[0]
+        obj.tx_packets = reader.read("!Q")[0]
+        obj.tx_errors = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.port_no != other.port_no: return False
+        if self.queue_id != other.queue_id: return False
+        if self.tx_bytes != other.tx_bytes: return False
+        if self.tx_packets != other.tx_packets: return False
+        if self.tx_errors != other.tx_errors: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("queue_id = ");
+                q.text("%#x" % self.queue_id)
+                q.text(","); q.breakable()
+                q.text("tx_bytes = ");
+                q.text("%#x" % self.tx_bytes)
+                q.text(","); q.breakable()
+                q.text("tx_packets = ");
+                q.text("%#x" % self.tx_packets)
+                q.text(","); q.breakable()
+                q.text("tx_errors = ");
+                q.text("%#x" % self.tx_errors)
+            q.breakable()
+        q.text('}')
+
+
+class table_stats_entry(loxi.OFObject):
+
+    def __init__(self, table_id=None, name=None, wildcards=None, match=None, instructions=None, write_actions=None, apply_actions=None, config=None, max_entries=None, active_count=None, lookup_count=None, matched_count=None):
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if name != None:
+            self.name = name
+        else:
+            self.name = ""
+        if wildcards != None:
+            self.wildcards = wildcards
+        else:
+            self.wildcards = util.init_wc_bmap()
+        if match != None:
+            self.match = match
+        else:
+            self.match = util.init_match_bmap()
+        if instructions != None:
+            self.instructions = instructions
+        else:
+            self.instructions = 0
+        if write_actions != None:
+            self.write_actions = write_actions
+        else:
+            self.write_actions = 0
+        if apply_actions != None:
+            self.apply_actions = apply_actions
+        else:
+            self.apply_actions = 0
+        if config != None:
+            self.config = config
+        else:
+            self.config = 0
+        if max_entries != None:
+            self.max_entries = max_entries
+        else:
+            self.max_entries = 0
+        if active_count != None:
+            self.active_count = active_count
+        else:
+            self.active_count = 0
+        if lookup_count != None:
+            self.lookup_count = lookup_count
+        else:
+            self.lookup_count = 0
+        if matched_count != None:
+            self.matched_count = matched_count
+        else:
+            self.matched_count = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append('\x00' * 7)
+        packed.append(struct.pack("!32s", self.name))
+        packed.append(util.pack_wc_bmap(self.wildcards))
+        packed.append(util.pack_match_bmap(self.match))
+        packed.append(struct.pack("!L", self.instructions))
+        packed.append(struct.pack("!L", self.write_actions))
+        packed.append(struct.pack("!L", self.apply_actions))
+        packed.append(struct.pack("!L", self.config))
+        packed.append(struct.pack("!L", self.max_entries))
+        packed.append(struct.pack("!L", self.active_count))
+        packed.append(struct.pack("!Q", self.lookup_count))
+        packed.append(struct.pack("!Q", self.matched_count))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_stats_entry()
+        obj.table_id = reader.read("!B")[0]
+        reader.skip(7)
+        obj.name = reader.read("!32s")[0].rstrip("\x00")
+        obj.wildcards = util.unpack_wc_bmap(reader)
+        obj.match = util.unpack_match_bmap(reader)
+        obj.instructions = reader.read("!L")[0]
+        obj.write_actions = reader.read("!L")[0]
+        obj.apply_actions = reader.read("!L")[0]
+        obj.config = reader.read("!L")[0]
+        obj.max_entries = reader.read("!L")[0]
+        obj.active_count = reader.read("!L")[0]
+        obj.lookup_count = reader.read("!Q")[0]
+        obj.matched_count = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.table_id != other.table_id: return False
+        if self.name != other.name: return False
+        if self.wildcards != other.wildcards: return False
+        if self.match != other.match: return False
+        if self.instructions != other.instructions: return False
+        if self.write_actions != other.write_actions: return False
+        if self.apply_actions != other.apply_actions: return False
+        if self.config != other.config: return False
+        if self.max_entries != other.max_entries: return False
+        if self.active_count != other.active_count: return False
+        if self.lookup_count != other.lookup_count: return False
+        if self.matched_count != other.matched_count: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("name = ");
+                q.pp(self.name)
+                q.text(","); q.breakable()
+                q.text("wildcards = ");
+                q.text(util.pretty_wildcards(self.wildcards))
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("instructions = ");
+                q.text("%#x" % self.instructions)
+                q.text(","); q.breakable()
+                q.text("write_actions = ");
+                q.text("%#x" % self.write_actions)
+                q.text(","); q.breakable()
+                q.text("apply_actions = ");
+                q.text("%#x" % self.apply_actions)
+                q.text(","); q.breakable()
+                q.text("config = ");
+                q.text("%#x" % self.config)
+                q.text(","); q.breakable()
+                q.text("max_entries = ");
+                q.text("%#x" % self.max_entries)
+                q.text(","); q.breakable()
+                q.text("active_count = ");
+                q.text("%#x" % self.active_count)
+                q.text(","); q.breakable()
+                q.text("lookup_count = ");
+                q.text("%#x" % self.lookup_count)
+                q.text(","); q.breakable()
+                q.text("matched_count = ");
+                q.text("%#x" % self.matched_count)
+            q.breakable()
+        q.text('}')
+
+
+
+match = match_v2
diff --git a/Fabric/Utilities/src/python/loxi/of11/const.py b/Fabric/Utilities/src/python/loxi/of11/const.py
new file mode 100644
index 0000000..b131b78
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of11/const.py
@@ -0,0 +1,736 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template const.py
+# Do not modify
+
+OFP_VERSION = 2
+
+# Identifiers from group macro_definitions
+OFP_MAX_TABLE_NAME_LEN = 32
+OFP_MAX_PORT_NAME_LEN = 16
+OFP_TCP_PORT = 6653
+OFP_SSL_PORT = 6653
+OFP_ETH_ALEN = 6
+OFP_DEFAULT_MISS_SEND_LEN = 128
+OFPFW_ICMP_TYPE = 64
+OFPFW_ICMP_CODE = 128
+OFP_DL_TYPE_ETH2_CUTOFF = 1536
+OFP_DL_TYPE_NOT_ETH_TYPE = 1535
+OFP_VLAN_NONE = 0
+OFPMT_STANDARD_LENGTH = 88
+OFP_FLOW_PERMANENT = 0
+OFP_DEFAULT_PRIORITY = 32768
+DESC_STR_LEN = 256
+SERIAL_NUM_LEN = 32
+OFPQ_ALL = 4294967295
+OFPQ_MIN_RATE_UNCFG = 65535
+
+# Identifiers from group of_bsn_pdu_slot_num
+BSN_PDU_SLOT_NUM_ANY = 255
+
+of_bsn_pdu_slot_num_map = {
+    255: 'BSN_PDU_SLOT_NUM_ANY',
+}
+
+# Identifiers from group ofp_action_type
+OFPAT_OUTPUT = 0
+OFPAT_SET_VLAN_VID = 1
+OFPAT_SET_VLAN_PCP = 2
+OFPAT_SET_DL_SRC = 3
+OFPAT_SET_DL_DST = 4
+OFPAT_SET_NW_SRC = 5
+OFPAT_SET_NW_DST = 6
+OFPAT_SET_NW_TOS = 7
+OFPAT_SET_NW_ECN = 8
+OFPAT_SET_TP_SRC = 9
+OFPAT_SET_TP_DST = 10
+OFPAT_COPY_TTL_OUT = 11
+OFPAT_COPY_TTL_IN = 12
+OFPAT_SET_MPLS_LABEL = 13
+OFPAT_SET_MPLS_TC = 14
+OFPAT_SET_MPLS_TTL = 15
+OFPAT_DEC_MPLS_TTL = 16
+OFPAT_PUSH_VLAN = 17
+OFPAT_POP_VLAN = 18
+OFPAT_PUSH_MPLS = 19
+OFPAT_POP_MPLS = 20
+OFPAT_SET_QUEUE = 21
+OFPAT_GROUP = 22
+OFPAT_SET_NW_TTL = 23
+OFPAT_DEC_NW_TTL = 24
+OFPAT_EXPERIMENTER = 65535
+
+ofp_action_type_map = {
+    0: 'OFPAT_OUTPUT',
+    1: 'OFPAT_SET_VLAN_VID',
+    2: 'OFPAT_SET_VLAN_PCP',
+    3: 'OFPAT_SET_DL_SRC',
+    4: 'OFPAT_SET_DL_DST',
+    5: 'OFPAT_SET_NW_SRC',
+    6: 'OFPAT_SET_NW_DST',
+    7: 'OFPAT_SET_NW_TOS',
+    8: 'OFPAT_SET_NW_ECN',
+    9: 'OFPAT_SET_TP_SRC',
+    10: 'OFPAT_SET_TP_DST',
+    11: 'OFPAT_COPY_TTL_OUT',
+    12: 'OFPAT_COPY_TTL_IN',
+    13: 'OFPAT_SET_MPLS_LABEL',
+    14: 'OFPAT_SET_MPLS_TC',
+    15: 'OFPAT_SET_MPLS_TTL',
+    16: 'OFPAT_DEC_MPLS_TTL',
+    17: 'OFPAT_PUSH_VLAN',
+    18: 'OFPAT_POP_VLAN',
+    19: 'OFPAT_PUSH_MPLS',
+    20: 'OFPAT_POP_MPLS',
+    21: 'OFPAT_SET_QUEUE',
+    22: 'OFPAT_GROUP',
+    23: 'OFPAT_SET_NW_TTL',
+    24: 'OFPAT_DEC_NW_TTL',
+    65535: 'OFPAT_EXPERIMENTER',
+}
+
+# Identifiers from group ofp_bad_action_code
+OFPBAC_BAD_TYPE = 0
+OFPBAC_BAD_LEN = 1
+OFPBAC_BAD_EXPERIMENTER = 2
+OFPBAC_BAD_EXPERIMENTER_TYPE = 3
+OFPBAC_BAD_OUT_PORT = 4
+OFPBAC_BAD_ARGUMENT = 5
+OFPBAC_EPERM = 6
+OFPBAC_TOO_MANY = 7
+OFPBAC_BAD_QUEUE = 8
+OFPBAC_BAD_OUT_GROUP = 9
+OFPBAC_MATCH_INCONSISTENT = 10
+OFPBAC_UNSUPPORTED_ORDER = 11
+OFPBAC_BAD_TAG = 12
+
+ofp_bad_action_code_map = {
+    0: 'OFPBAC_BAD_TYPE',
+    1: 'OFPBAC_BAD_LEN',
+    2: 'OFPBAC_BAD_EXPERIMENTER',
+    3: 'OFPBAC_BAD_EXPERIMENTER_TYPE',
+    4: 'OFPBAC_BAD_OUT_PORT',
+    5: 'OFPBAC_BAD_ARGUMENT',
+    6: 'OFPBAC_EPERM',
+    7: 'OFPBAC_TOO_MANY',
+    8: 'OFPBAC_BAD_QUEUE',
+    9: 'OFPBAC_BAD_OUT_GROUP',
+    10: 'OFPBAC_MATCH_INCONSISTENT',
+    11: 'OFPBAC_UNSUPPORTED_ORDER',
+    12: 'OFPBAC_BAD_TAG',
+}
+
+# Identifiers from group ofp_bad_instruction_code
+OFPBIC_UNKNOWN_INST = 0
+OFPBIC_UNSUP_INST = 1
+OFPBIC_BAD_TABLE_ID = 2
+OFPBIC_UNSUP_METADATA = 3
+OFPBIC_UNSUP_METADATA_MASK = 4
+OFPBIC_UNSUP_EXP_INST = 5
+
+ofp_bad_instruction_code_map = {
+    0: 'OFPBIC_UNKNOWN_INST',
+    1: 'OFPBIC_UNSUP_INST',
+    2: 'OFPBIC_BAD_TABLE_ID',
+    3: 'OFPBIC_UNSUP_METADATA',
+    4: 'OFPBIC_UNSUP_METADATA_MASK',
+    5: 'OFPBIC_UNSUP_EXP_INST',
+}
+
+# Identifiers from group ofp_bad_match_code
+OFPBMC_BAD_TYPE = 0
+OFPBMC_BAD_LEN = 1
+OFPBMC_BAD_TAG = 2
+OFPBMC_BAD_DL_ADDR_MASK = 3
+OFPBMC_BAD_NW_ADDR_MASK = 4
+OFPBMC_BAD_WILDCARDS = 5
+OFPBMC_BAD_FIELD = 6
+OFPBMC_BAD_VALUE = 7
+
+ofp_bad_match_code_map = {
+    0: 'OFPBMC_BAD_TYPE',
+    1: 'OFPBMC_BAD_LEN',
+    2: 'OFPBMC_BAD_TAG',
+    3: 'OFPBMC_BAD_DL_ADDR_MASK',
+    4: 'OFPBMC_BAD_NW_ADDR_MASK',
+    5: 'OFPBMC_BAD_WILDCARDS',
+    6: 'OFPBMC_BAD_FIELD',
+    7: 'OFPBMC_BAD_VALUE',
+}
+
+# Identifiers from group ofp_bad_request_code
+OFPBRC_BAD_VERSION = 0
+OFPBRC_BAD_TYPE = 1
+OFPBRC_BAD_STAT = 2
+OFPBRC_BAD_EXPERIMENTER = 3
+OFPBRC_BAD_SUBTYPE = 4
+OFPBRC_EPERM = 5
+OFPBRC_BAD_LEN = 6
+OFPBRC_BUFFER_EMPTY = 7
+OFPBRC_BUFFER_UNKNOWN = 8
+OFPBRC_BAD_TABLE_ID = 9
+
+ofp_bad_request_code_map = {
+    0: 'OFPBRC_BAD_VERSION',
+    1: 'OFPBRC_BAD_TYPE',
+    2: 'OFPBRC_BAD_STAT',
+    3: 'OFPBRC_BAD_EXPERIMENTER',
+    4: 'OFPBRC_BAD_SUBTYPE',
+    5: 'OFPBRC_EPERM',
+    6: 'OFPBRC_BAD_LEN',
+    7: 'OFPBRC_BUFFER_EMPTY',
+    8: 'OFPBRC_BUFFER_UNKNOWN',
+    9: 'OFPBRC_BAD_TABLE_ID',
+}
+
+# Identifiers from group ofp_bsn_vport_l2gre_flags
+OF_BSN_VPORT_L2GRE_LOCAL_MAC_IS_VALID = 1
+OF_BSN_VPORT_L2GRE_DSCP_ASSIGN = 2
+OF_BSN_VPORT_L2GRE_DSCP_COPY = 4
+OF_BSN_VPORT_L2GRE_LOOPBACK_IS_VALID = 8
+OF_BSN_VPORT_L2GRE_RATE_LIMIT_IS_VALID = 16
+
+ofp_bsn_vport_l2gre_flags_map = {
+    1: 'OF_BSN_VPORT_L2GRE_LOCAL_MAC_IS_VALID',
+    2: 'OF_BSN_VPORT_L2GRE_DSCP_ASSIGN',
+    4: 'OF_BSN_VPORT_L2GRE_DSCP_COPY',
+    8: 'OF_BSN_VPORT_L2GRE_LOOPBACK_IS_VALID',
+    16: 'OF_BSN_VPORT_L2GRE_RATE_LIMIT_IS_VALID',
+}
+
+# Identifiers from group ofp_bsn_vport_q_in_q_untagged
+OF_BSN_VPORT_Q_IN_Q_UNTAGGED = 65535
+
+ofp_bsn_vport_q_in_q_untagged_map = {
+    65535: 'OF_BSN_VPORT_Q_IN_Q_UNTAGGED',
+}
+
+# Identifiers from group ofp_bsn_vport_status
+OF_BSN_VPORT_STATUS_OK = 0
+OF_BSN_VPORT_STATUS_FAILED = 1
+
+ofp_bsn_vport_status_map = {
+    0: 'OF_BSN_VPORT_STATUS_OK',
+    1: 'OF_BSN_VPORT_STATUS_FAILED',
+}
+
+# Identifiers from group ofp_capabilities
+OFPC_FLOW_STATS = 1
+OFPC_TABLE_STATS = 2
+OFPC_PORT_STATS = 4
+OFPC_GROUP_STATS = 8
+OFPC_IP_REASM = 32
+OFPC_QUEUE_STATS = 64
+OFPC_ARP_MATCH_IP = 128
+
+ofp_capabilities_map = {
+    1: 'OFPC_FLOW_STATS',
+    2: 'OFPC_TABLE_STATS',
+    4: 'OFPC_PORT_STATS',
+    8: 'OFPC_GROUP_STATS',
+    32: 'OFPC_IP_REASM',
+    64: 'OFPC_QUEUE_STATS',
+    128: 'OFPC_ARP_MATCH_IP',
+}
+
+# Identifiers from group ofp_config_flags
+OFPC_FRAG_NORMAL = 0
+OFPC_FRAG_DROP = 1
+OFPC_FRAG_REASM = 2
+OFPC_FRAG_MASK = 3
+OFPC_INVALID_TTL_TO_CONTROLLER = 4
+
+ofp_config_flags_map = {
+    0: 'OFPC_FRAG_NORMAL',
+    1: 'OFPC_FRAG_DROP',
+    2: 'OFPC_FRAG_REASM',
+    3: 'OFPC_FRAG_MASK',
+    4: 'OFPC_INVALID_TTL_TO_CONTROLLER',
+}
+
+# Identifiers from group ofp_error_type
+OFPET_HELLO_FAILED = 0
+OFPET_BAD_REQUEST = 1
+OFPET_BAD_ACTION = 2
+OFPET_BAD_INSTRUCTION = 3
+OFPET_BAD_MATCH = 4
+OFPET_FLOW_MOD_FAILED = 5
+OFPET_GROUP_MOD_FAILED = 6
+OFPET_PORT_MOD_FAILED = 7
+OFPET_TABLE_MOD_FAILED = 8
+OFPET_QUEUE_OP_FAILED = 9
+OFPET_SWITCH_CONFIG_FAILED = 10
+
+ofp_error_type_map = {
+    0: 'OFPET_HELLO_FAILED',
+    1: 'OFPET_BAD_REQUEST',
+    2: 'OFPET_BAD_ACTION',
+    3: 'OFPET_BAD_INSTRUCTION',
+    4: 'OFPET_BAD_MATCH',
+    5: 'OFPET_FLOW_MOD_FAILED',
+    6: 'OFPET_GROUP_MOD_FAILED',
+    7: 'OFPET_PORT_MOD_FAILED',
+    8: 'OFPET_TABLE_MOD_FAILED',
+    9: 'OFPET_QUEUE_OP_FAILED',
+    10: 'OFPET_SWITCH_CONFIG_FAILED',
+}
+
+# Identifiers from group ofp_flow_mod_command
+OFPFC_ADD = 0
+OFPFC_MODIFY = 1
+OFPFC_MODIFY_STRICT = 2
+OFPFC_DELETE = 3
+OFPFC_DELETE_STRICT = 4
+
+ofp_flow_mod_command_map = {
+    0: 'OFPFC_ADD',
+    1: 'OFPFC_MODIFY',
+    2: 'OFPFC_MODIFY_STRICT',
+    3: 'OFPFC_DELETE',
+    4: 'OFPFC_DELETE_STRICT',
+}
+
+# Identifiers from group ofp_flow_mod_failed_code
+OFPFMFC_UNKNOWN = 0
+OFPFMFC_TABLE_FULL = 1
+OFPFMFC_BAD_TABLE_ID = 2
+OFPFMFC_OVERLAP = 3
+OFPFMFC_EPERM = 4
+OFPFMFC_BAD_TIMEOUT = 5
+OFPFMFC_BAD_COMMAND = 6
+
+ofp_flow_mod_failed_code_map = {
+    0: 'OFPFMFC_UNKNOWN',
+    1: 'OFPFMFC_TABLE_FULL',
+    2: 'OFPFMFC_BAD_TABLE_ID',
+    3: 'OFPFMFC_OVERLAP',
+    4: 'OFPFMFC_EPERM',
+    5: 'OFPFMFC_BAD_TIMEOUT',
+    6: 'OFPFMFC_BAD_COMMAND',
+}
+
+# Identifiers from group ofp_flow_mod_flags
+OFPFF_SEND_FLOW_REM = 1
+OFPFF_CHECK_OVERLAP = 2
+
+ofp_flow_mod_flags_map = {
+    1: 'OFPFF_SEND_FLOW_REM',
+    2: 'OFPFF_CHECK_OVERLAP',
+}
+
+# Identifiers from group ofp_flow_removed_reason
+OFPRR_IDLE_TIMEOUT = 0
+OFPRR_HARD_TIMEOUT = 1
+OFPRR_DELETE = 2
+OFPRR_GROUP_DELETE = 3
+
+ofp_flow_removed_reason_map = {
+    0: 'OFPRR_IDLE_TIMEOUT',
+    1: 'OFPRR_HARD_TIMEOUT',
+    2: 'OFPRR_DELETE',
+    3: 'OFPRR_GROUP_DELETE',
+}
+
+# Identifiers from group ofp_flow_wildcards
+OFPFW_IN_PORT = 1
+OFPFW_DL_VLAN = 2
+OFPFW_DL_VLAN_PCP = 4
+OFPFW_DL_TYPE = 8
+OFPFW_NW_TOS = 16
+OFPFW_NW_PROTO = 32
+OFPFW_TP_SRC = 64
+OFPFW_TP_DST = 128
+OFPFW_MPLS_LABEL = 256
+OFPFW_MPLS_TC = 512
+OFPFW_ALL = 1023
+
+ofp_flow_wildcards_map = {
+    1: 'OFPFW_IN_PORT',
+    2: 'OFPFW_DL_VLAN',
+    4: 'OFPFW_DL_VLAN_PCP',
+    8: 'OFPFW_DL_TYPE',
+    16: 'OFPFW_NW_TOS',
+    32: 'OFPFW_NW_PROTO',
+    64: 'OFPFW_TP_SRC',
+    128: 'OFPFW_TP_DST',
+    256: 'OFPFW_MPLS_LABEL',
+    512: 'OFPFW_MPLS_TC',
+}
+
+# Identifiers from group ofp_group
+OFPG_MAX = 4294967040
+OFPG_ALL = 4294967292
+OFPG_ANY = 4294967295
+
+ofp_group_map = {
+    4294967040: 'OFPG_MAX',
+    4294967292: 'OFPG_ALL',
+    4294967295: 'OFPG_ANY',
+}
+
+# Identifiers from group ofp_group_mod_command
+OFPGC_ADD = 0
+OFPGC_MODIFY = 1
+OFPGC_DELETE = 2
+
+ofp_group_mod_command_map = {
+    0: 'OFPGC_ADD',
+    1: 'OFPGC_MODIFY',
+    2: 'OFPGC_DELETE',
+}
+
+# Identifiers from group ofp_group_mod_failed_code
+OFPGMFC_GROUP_EXISTS = 0
+OFPGMFC_INVALID_GROUP = 1
+OFPGMFC_WEIGHT_UNSUPPORTED = 2
+OFPGMFC_OUT_OF_GROUPS = 3
+OFPGMFC_OUT_OF_BUCKETS = 4
+OFPGMFC_CHAINING_UNSUPPORTED = 5
+OFPGMFC_WATCH_UNSUPPORTED = 6
+OFPGMFC_LOOP = 7
+OFPGMFC_UNKNOWN_GROUP = 8
+
+ofp_group_mod_failed_code_map = {
+    0: 'OFPGMFC_GROUP_EXISTS',
+    1: 'OFPGMFC_INVALID_GROUP',
+    2: 'OFPGMFC_WEIGHT_UNSUPPORTED',
+    3: 'OFPGMFC_OUT_OF_GROUPS',
+    4: 'OFPGMFC_OUT_OF_BUCKETS',
+    5: 'OFPGMFC_CHAINING_UNSUPPORTED',
+    6: 'OFPGMFC_WATCH_UNSUPPORTED',
+    7: 'OFPGMFC_LOOP',
+    8: 'OFPGMFC_UNKNOWN_GROUP',
+}
+
+# Identifiers from group ofp_group_type
+OFPGT_ALL = 0
+OFPGT_SELECT = 1
+OFPGT_INDIRECT = 2
+OFPGT_FF = 3
+
+ofp_group_type_map = {
+    0: 'OFPGT_ALL',
+    1: 'OFPGT_SELECT',
+    2: 'OFPGT_INDIRECT',
+    3: 'OFPGT_FF',
+}
+
+# Identifiers from group ofp_hello_failed_code
+OFPHFC_INCOMPATIBLE = 0
+OFPHFC_EPERM = 1
+
+ofp_hello_failed_code_map = {
+    0: 'OFPHFC_INCOMPATIBLE',
+    1: 'OFPHFC_EPERM',
+}
+
+# Identifiers from group ofp_instruction_type
+OFPIT_GOTO_TABLE = 1
+OFPIT_WRITE_METADATA = 2
+OFPIT_WRITE_ACTIONS = 3
+OFPIT_APPLY_ACTIONS = 4
+OFPIT_CLEAR_ACTIONS = 5
+OFPIT_EXPERIMENTER = 65535
+
+ofp_instruction_type_map = {
+    1: 'OFPIT_GOTO_TABLE',
+    2: 'OFPIT_WRITE_METADATA',
+    3: 'OFPIT_WRITE_ACTIONS',
+    4: 'OFPIT_APPLY_ACTIONS',
+    5: 'OFPIT_CLEAR_ACTIONS',
+    65535: 'OFPIT_EXPERIMENTER',
+}
+
+# Identifiers from group ofp_match_type
+OFPMT_STANDARD = 0
+
+ofp_match_type_map = {
+    0: 'OFPMT_STANDARD',
+}
+
+# Identifiers from group ofp_packet_in_reason
+OFPR_NO_MATCH = 0
+OFPR_ACTION = 1
+
+ofp_packet_in_reason_map = {
+    0: 'OFPR_NO_MATCH',
+    1: 'OFPR_ACTION',
+}
+
+# Identifiers from group ofp_port
+OFPP_MAX = 4294967040
+OFPP_IN_PORT = 4294967288
+OFPP_TABLE = 4294967289
+OFPP_NORMAL = 4294967290
+OFPP_FLOOD = 4294967291
+OFPP_ALL = 4294967292
+OFPP_CONTROLLER = 4294967293
+OFPP_LOCAL = 4294967294
+OFPP_ANY = 4294967295
+
+ofp_port_map = {
+    4294967040: 'OFPP_MAX',
+    4294967288: 'OFPP_IN_PORT',
+    4294967289: 'OFPP_TABLE',
+    4294967290: 'OFPP_NORMAL',
+    4294967291: 'OFPP_FLOOD',
+    4294967292: 'OFPP_ALL',
+    4294967293: 'OFPP_CONTROLLER',
+    4294967294: 'OFPP_LOCAL',
+    4294967295: 'OFPP_ANY',
+}
+
+# Identifiers from group ofp_port_config
+OFPPC_PORT_DOWN = 1
+OFPPC_NO_RECV = 4
+OFPPC_NO_FWD = 32
+OFPPC_NO_PACKET_IN = 64
+OFPPC_BSN_MIRROR_DEST = 2147483648
+
+ofp_port_config_map = {
+    1: 'OFPPC_PORT_DOWN',
+    4: 'OFPPC_NO_RECV',
+    32: 'OFPPC_NO_FWD',
+    64: 'OFPPC_NO_PACKET_IN',
+    2147483648: 'OFPPC_BSN_MIRROR_DEST',
+}
+
+# Identifiers from group ofp_port_features
+OFPPF_10MB_HD = 1
+OFPPF_10MB_FD = 2
+OFPPF_100MB_HD = 4
+OFPPF_100MB_FD = 8
+OFPPF_1GB_HD = 16
+OFPPF_1GB_FD = 32
+OFPPF_10GB_FD = 64
+OFPPF_40GB_FD = 128
+OFPPF_100GB_FD = 256
+OFPPF_1TB_FD = 512
+OFPPF_OTHER = 1024
+OFPPF_COPPER = 2048
+OFPPF_FIBER = 4096
+OFPPF_AUTONEG = 8192
+OFPPF_PAUSE = 16384
+OFPPF_PAUSE_ASYM = 32768
+
+ofp_port_features_map = {
+    1: 'OFPPF_10MB_HD',
+    2: 'OFPPF_10MB_FD',
+    4: 'OFPPF_100MB_HD',
+    8: 'OFPPF_100MB_FD',
+    16: 'OFPPF_1GB_HD',
+    32: 'OFPPF_1GB_FD',
+    64: 'OFPPF_10GB_FD',
+    128: 'OFPPF_40GB_FD',
+    256: 'OFPPF_100GB_FD',
+    512: 'OFPPF_1TB_FD',
+    1024: 'OFPPF_OTHER',
+    2048: 'OFPPF_COPPER',
+    4096: 'OFPPF_FIBER',
+    8192: 'OFPPF_AUTONEG',
+    16384: 'OFPPF_PAUSE',
+    32768: 'OFPPF_PAUSE_ASYM',
+}
+
+# Identifiers from group ofp_port_mod_failed_code
+OFPPMFC_BAD_PORT = 0
+OFPPMFC_BAD_HW_ADDR = 1
+OFPPMFC_BAD_CONFIG = 2
+OFPPMFC_BAD_ADVERTISE = 3
+
+ofp_port_mod_failed_code_map = {
+    0: 'OFPPMFC_BAD_PORT',
+    1: 'OFPPMFC_BAD_HW_ADDR',
+    2: 'OFPPMFC_BAD_CONFIG',
+    3: 'OFPPMFC_BAD_ADVERTISE',
+}
+
+# Identifiers from group ofp_port_reason
+OFPPR_ADD = 0
+OFPPR_DELETE = 1
+OFPPR_MODIFY = 2
+
+ofp_port_reason_map = {
+    0: 'OFPPR_ADD',
+    1: 'OFPPR_DELETE',
+    2: 'OFPPR_MODIFY',
+}
+
+# Identifiers from group ofp_port_state
+OFPPS_LINK_DOWN = 1
+OFPPS_BLOCKED = 2
+OFPPS_LIVE = 4
+
+ofp_port_state_map = {
+    1: 'OFPPS_LINK_DOWN',
+    2: 'OFPPS_BLOCKED',
+    4: 'OFPPS_LIVE',
+}
+
+# Identifiers from group ofp_queue_op_failed_code
+OFPQOFC_BAD_PORT = 0
+OFPQOFC_BAD_QUEUE = 1
+OFPQOFC_EPERM = 2
+
+ofp_queue_op_failed_code_map = {
+    0: 'OFPQOFC_BAD_PORT',
+    1: 'OFPQOFC_BAD_QUEUE',
+    2: 'OFPQOFC_EPERM',
+}
+
+# Identifiers from group ofp_queue_properties
+OFPQT_NONE = 0
+OFPQT_MIN_RATE = 1
+
+ofp_queue_properties_map = {
+    0: 'OFPQT_NONE',
+    1: 'OFPQT_MIN_RATE',
+}
+
+# Identifiers from group ofp_stats_reply_flags
+OFPSF_REPLY_MORE = 1
+
+ofp_stats_reply_flags_map = {
+    1: 'OFPSF_REPLY_MORE',
+}
+
+# Identifiers from group ofp_stats_request_flags
+
+ofp_stats_request_flags_map = {
+}
+
+# Identifiers from group ofp_stats_type
+OFPST_DESC = 0
+OFPST_FLOW = 1
+OFPST_AGGREGATE = 2
+OFPST_TABLE = 3
+OFPST_PORT = 4
+OFPST_QUEUE = 5
+OFPST_GROUP = 6
+OFPST_GROUP_DESC = 7
+OFPST_EXPERIMENTER = 65535
+
+ofp_stats_type_map = {
+    0: 'OFPST_DESC',
+    1: 'OFPST_FLOW',
+    2: 'OFPST_AGGREGATE',
+    3: 'OFPST_TABLE',
+    4: 'OFPST_PORT',
+    5: 'OFPST_QUEUE',
+    6: 'OFPST_GROUP',
+    7: 'OFPST_GROUP_DESC',
+    65535: 'OFPST_EXPERIMENTER',
+}
+
+# Identifiers from group ofp_switch_config_failed_code
+OFPSCFC_BAD_FLAGS = 0
+OFPSCFC_BAD_LEN = 1
+
+ofp_switch_config_failed_code_map = {
+    0: 'OFPSCFC_BAD_FLAGS',
+    1: 'OFPSCFC_BAD_LEN',
+}
+
+# Identifiers from group ofp_table_config
+OFPTC_TABLE_MISS_CONTROLLER = 0
+OFPTC_TABLE_MISS_CONTINUE = 1
+OFPTC_TABLE_MISS_DROP = 2
+OFPTC_TABLE_MISS_MASK = 3
+
+ofp_table_config_map = {
+    0: 'OFPTC_TABLE_MISS_CONTROLLER',
+    1: 'OFPTC_TABLE_MISS_CONTINUE',
+    2: 'OFPTC_TABLE_MISS_DROP',
+    3: 'OFPTC_TABLE_MISS_MASK',
+}
+
+# Identifiers from group ofp_table_mod_failed_code
+OFPTMFC_BAD_TABLE = 0
+OFPTMFC_BAD_CONFIG = 1
+
+ofp_table_mod_failed_code_map = {
+    0: 'OFPTMFC_BAD_TABLE',
+    1: 'OFPTMFC_BAD_CONFIG',
+}
+
+# Identifiers from group ofp_type
+OFPT_HELLO = 0
+OFPT_ERROR = 1
+OFPT_ECHO_REQUEST = 2
+OFPT_ECHO_REPLY = 3
+OFPT_EXPERIMENTER = 4
+OFPT_FEATURES_REQUEST = 5
+OFPT_FEATURES_REPLY = 6
+OFPT_GET_CONFIG_REQUEST = 7
+OFPT_GET_CONFIG_REPLY = 8
+OFPT_SET_CONFIG = 9
+OFPT_PACKET_IN = 10
+OFPT_FLOW_REMOVED = 11
+OFPT_PORT_STATUS = 12
+OFPT_PACKET_OUT = 13
+OFPT_FLOW_MOD = 14
+OFPT_GROUP_MOD = 15
+OFPT_PORT_MOD = 16
+OFPT_TABLE_MOD = 17
+OFPT_STATS_REQUEST = 18
+OFPT_STATS_REPLY = 19
+OFPT_BARRIER_REQUEST = 20
+OFPT_BARRIER_REPLY = 21
+OFPT_QUEUE_GET_CONFIG_REQUEST = 22
+OFPT_QUEUE_GET_CONFIG_REPLY = 23
+
+ofp_type_map = {
+    0: 'OFPT_HELLO',
+    1: 'OFPT_ERROR',
+    2: 'OFPT_ECHO_REQUEST',
+    3: 'OFPT_ECHO_REPLY',
+    4: 'OFPT_EXPERIMENTER',
+    5: 'OFPT_FEATURES_REQUEST',
+    6: 'OFPT_FEATURES_REPLY',
+    7: 'OFPT_GET_CONFIG_REQUEST',
+    8: 'OFPT_GET_CONFIG_REPLY',
+    9: 'OFPT_SET_CONFIG',
+    10: 'OFPT_PACKET_IN',
+    11: 'OFPT_FLOW_REMOVED',
+    12: 'OFPT_PORT_STATUS',
+    13: 'OFPT_PACKET_OUT',
+    14: 'OFPT_FLOW_MOD',
+    15: 'OFPT_GROUP_MOD',
+    16: 'OFPT_PORT_MOD',
+    17: 'OFPT_TABLE_MOD',
+    18: 'OFPT_STATS_REQUEST',
+    19: 'OFPT_STATS_REPLY',
+    20: 'OFPT_BARRIER_REQUEST',
+    21: 'OFPT_BARRIER_REPLY',
+    22: 'OFPT_QUEUE_GET_CONFIG_REQUEST',
+    23: 'OFPT_QUEUE_GET_CONFIG_REPLY',
+}
+
+# Identifiers from group ofp_vlan_id
+OFPVID_ANY = 65534
+OFPVID_NONE = 65535
+
+ofp_vlan_id_map = {
+    65534: 'OFPVID_ANY',
+    65535: 'OFPVID_NONE',
+}
+
diff --git a/Fabric/Utilities/src/python/loxi/of11/instruction.py b/Fabric/Utilities/src/python/loxi/of11/instruction.py
new file mode 100644
index 0000000..eb0f517
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of11/instruction.py
@@ -0,0 +1,389 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of11']
+
+class instruction(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = instruction.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = instruction()
+        obj.type = reader.read("!H")[0]
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("instruction {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class apply_actions(instruction):
+    type = 4
+
+    def __init__(self, actions=None):
+        if actions != None:
+            self.actions = actions
+        else:
+            self.actions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.actions))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = apply_actions()
+        _type = reader.read("!H")[0]
+        assert(_type == 4)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        obj.actions = loxi.generic_util.unpack_list(reader, ofp.action.action.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.actions != other.actions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("apply_actions {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("actions = ");
+                q.pp(self.actions)
+            q.breakable()
+        q.text('}')
+
+instruction.subtypes[4] = apply_actions
+
+class clear_actions(instruction):
+    type = 5
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = clear_actions()
+        _type = reader.read("!H")[0]
+        assert(_type == 5)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("clear_actions {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+instruction.subtypes[5] = clear_actions
+
+class experimenter(instruction):
+    subtypes = {}
+
+    type = 65535
+
+    def __init__(self, experimenter=None, data=None):
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 4)
+        subclass = experimenter.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = experimenter()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.experimenter = reader.read("!L")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.experimenter != other.experimenter: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+instruction.subtypes[65535] = experimenter
+
+class goto_table(instruction):
+    type = 1
+
+    def __init__(self, table_id=None):
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = goto_table()
+        _type = reader.read("!H")[0]
+        assert(_type == 1)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.table_id = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.table_id != other.table_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("goto_table {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+            q.breakable()
+        q.text('}')
+
+instruction.subtypes[1] = goto_table
+
+class write_actions(instruction):
+    type = 3
+
+    def __init__(self, actions=None):
+        if actions != None:
+            self.actions = actions
+        else:
+            self.actions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.actions))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = write_actions()
+        _type = reader.read("!H")[0]
+        assert(_type == 3)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        obj.actions = loxi.generic_util.unpack_list(reader, ofp.action.action.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.actions != other.actions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("write_actions {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("actions = ");
+                q.pp(self.actions)
+            q.breakable()
+        q.text('}')
+
+instruction.subtypes[3] = write_actions
+
+class write_metadata(instruction):
+    type = 2
+
+    def __init__(self, metadata=None, metadata_mask=None):
+        if metadata != None:
+            self.metadata = metadata
+        else:
+            self.metadata = 0
+        if metadata_mask != None:
+            self.metadata_mask = metadata_mask
+        else:
+            self.metadata_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!Q", self.metadata))
+        packed.append(struct.pack("!Q", self.metadata_mask))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = write_metadata()
+        _type = reader.read("!H")[0]
+        assert(_type == 2)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        obj.metadata = reader.read("!Q")[0]
+        obj.metadata_mask = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.metadata != other.metadata: return False
+        if self.metadata_mask != other.metadata_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("write_metadata {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("metadata = ");
+                q.text("%#x" % self.metadata)
+                q.text(","); q.breakable()
+                q.text("metadata_mask = ");
+                q.text("%#x" % self.metadata_mask)
+            q.breakable()
+        q.text('}')
+
+instruction.subtypes[2] = write_metadata
+
+
diff --git a/Fabric/Utilities/src/python/loxi/of11/message.py b/Fabric/Utilities/src/python/loxi/of11/message.py
new file mode 100644
index 0000000..77ab080
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of11/message.py
@@ -0,0 +1,7859 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of11']
+
+class message(loxi.OFObject):
+    subtypes = {}
+
+    version = 2
+
+    def __init__(self, type=None, xid=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('B', 1)
+        subclass = message.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = message()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        obj.type = reader.read("!B")[0]
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("message {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+
+class stats_reply(message):
+    subtypes = {}
+
+    version = 2
+    type = 19
+
+    def __init__(self, xid=None, stats_type=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if stats_type != None:
+            self.stats_type = stats_type
+        else:
+            self.stats_type = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 8)
+        subclass = stats_reply.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.stats_type = reader.read("!H")[0]
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.stats_type != other.stats_type: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[19] = stats_reply
+
+class aggregate_stats_reply(stats_reply):
+    version = 2
+    type = 19
+    stats_type = 2
+
+    def __init__(self, xid=None, flags=None, packet_count=None, byte_count=None, flow_count=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if packet_count != None:
+            self.packet_count = packet_count
+        else:
+            self.packet_count = 0
+        if byte_count != None:
+            self.byte_count = byte_count
+        else:
+            self.byte_count = 0
+        if flow_count != None:
+            self.flow_count = flow_count
+        else:
+            self.flow_count = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!Q", self.packet_count))
+        packed.append(struct.pack("!Q", self.byte_count))
+        packed.append(struct.pack("!L", self.flow_count))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = aggregate_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 2)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.packet_count = reader.read("!Q")[0]
+        obj.byte_count = reader.read("!Q")[0]
+        obj.flow_count = reader.read("!L")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.packet_count != other.packet_count: return False
+        if self.byte_count != other.byte_count: return False
+        if self.flow_count != other.flow_count: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("aggregate_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("packet_count = ");
+                q.text("%#x" % self.packet_count)
+                q.text(","); q.breakable()
+                q.text("byte_count = ");
+                q.text("%#x" % self.byte_count)
+                q.text(","); q.breakable()
+                q.text("flow_count = ");
+                q.text("%#x" % self.flow_count)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[2] = aggregate_stats_reply
+
+class stats_request(message):
+    subtypes = {}
+
+    version = 2
+    type = 18
+
+    def __init__(self, xid=None, stats_type=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if stats_type != None:
+            self.stats_type = stats_type
+        else:
+            self.stats_type = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 8)
+        subclass = stats_request.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.stats_type = reader.read("!H")[0]
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.stats_type != other.stats_type: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[18] = stats_request
+
+class aggregate_stats_request(stats_request):
+    version = 2
+    type = 18
+    stats_type = 2
+
+    def __init__(self, xid=None, flags=None, table_id=None, out_port=None, out_group=None, cookie=None, cookie_mask=None, match=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if out_group != None:
+            self.out_group = out_group
+        else:
+            self.out_group = 0
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if cookie_mask != None:
+            self.cookie_mask = cookie_mask
+        else:
+            self.cookie_mask = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append('\x00' * 3)
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!L", self.out_group))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.cookie_mask))
+        packed.append(self.match.pack())
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = aggregate_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 2)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.table_id = reader.read("!B")[0]
+        reader.skip(3)
+        obj.out_port = util.unpack_port_no(reader)
+        obj.out_group = reader.read("!L")[0]
+        reader.skip(4)
+        obj.cookie = reader.read("!Q")[0]
+        obj.cookie_mask = reader.read("!Q")[0]
+        obj.match = ofp.match.unpack(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.table_id != other.table_id: return False
+        if self.out_port != other.out_port: return False
+        if self.out_group != other.out_group: return False
+        if self.cookie != other.cookie: return False
+        if self.cookie_mask != other.cookie_mask: return False
+        if self.match != other.match: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("aggregate_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("out_group = ");
+                q.text("%#x" % self.out_group)
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("cookie_mask = ");
+                q.text("%#x" % self.cookie_mask)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[2] = aggregate_stats_request
+
+class error_msg(message):
+    subtypes = {}
+
+    version = 2
+    type = 1
+
+    def __init__(self, xid=None, err_type=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if err_type != None:
+            self.err_type = err_type
+        else:
+            self.err_type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 8)
+        subclass = error_msg.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.err_type = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.err_type != other.err_type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+message.subtypes[1] = error_msg
+
+class bad_action_error_msg(error_msg):
+    version = 2
+    type = 1
+    err_type = 2
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bad_action_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 2)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bad_action_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[2] = bad_action_error_msg
+
+class bad_instruction_error_msg(error_msg):
+    version = 2
+    type = 1
+    err_type = 3
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bad_instruction_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 3)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bad_instruction_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[3] = bad_instruction_error_msg
+
+class bad_match_error_msg(error_msg):
+    version = 2
+    type = 1
+    err_type = 4
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bad_match_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 4)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bad_match_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[4] = bad_match_error_msg
+
+class bad_request_error_msg(error_msg):
+    version = 2
+    type = 1
+    err_type = 1
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bad_request_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 1)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bad_request_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[1] = bad_request_error_msg
+
+class barrier_reply(message):
+    version = 2
+    type = 21
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = barrier_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 21)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("barrier_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+message.subtypes[21] = barrier_reply
+
+class barrier_request(message):
+    version = 2
+    type = 20
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = barrier_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 20)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("barrier_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+message.subtypes[20] = barrier_request
+
+class experimenter(message):
+    subtypes = {}
+
+    version = 2
+    type = 4
+
+    def __init__(self, xid=None, experimenter=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 8)
+        subclass = experimenter.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = experimenter()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.experimenter = reader.read("!L")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.experimenter != other.experimenter: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[4] = experimenter
+
+class bsn_header(experimenter):
+    subtypes = {}
+
+    version = 2
+    type = 4
+    experimenter = 6035143
+
+    def __init__(self, xid=None, subtype=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 12)
+        subclass = bsn_header.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = bsn_header()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        obj.subtype = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_header {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+experimenter.subtypes[6035143] = bsn_header
+
+class bsn_bw_clear_data_reply(bsn_header):
+    version = 2
+    type = 4
+    experimenter = 6035143
+    subtype = 22
+
+    def __init__(self, xid=None, status=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.status))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_bw_clear_data_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 22)
+        obj.status = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.status != other.status: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_bw_clear_data_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[22] = bsn_bw_clear_data_reply
+
+class bsn_bw_clear_data_request(bsn_header):
+    version = 2
+    type = 4
+    experimenter = 6035143
+    subtype = 21
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_bw_clear_data_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 21)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_bw_clear_data_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[21] = bsn_bw_clear_data_request
+
+class bsn_bw_enable_get_reply(bsn_header):
+    version = 2
+    type = 4
+    experimenter = 6035143
+    subtype = 20
+
+    def __init__(self, xid=None, enabled=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if enabled != None:
+            self.enabled = enabled
+        else:
+            self.enabled = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.enabled))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_bw_enable_get_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 20)
+        obj.enabled = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.enabled != other.enabled: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_bw_enable_get_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("enabled = ");
+                q.text("%#x" % self.enabled)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[20] = bsn_bw_enable_get_reply
+
+class bsn_bw_enable_get_request(bsn_header):
+    version = 2
+    type = 4
+    experimenter = 6035143
+    subtype = 19
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_bw_enable_get_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 19)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_bw_enable_get_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[19] = bsn_bw_enable_get_request
+
+class bsn_bw_enable_set_reply(bsn_header):
+    version = 2
+    type = 4
+    experimenter = 6035143
+    subtype = 23
+
+    def __init__(self, xid=None, enable=None, status=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if enable != None:
+            self.enable = enable
+        else:
+            self.enable = 0
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.enable))
+        packed.append(struct.pack("!L", self.status))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_bw_enable_set_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 23)
+        obj.enable = reader.read("!L")[0]
+        obj.status = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.enable != other.enable: return False
+        if self.status != other.status: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_bw_enable_set_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("enable = ");
+                q.text("%#x" % self.enable)
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[23] = bsn_bw_enable_set_reply
+
+class bsn_bw_enable_set_request(bsn_header):
+    version = 2
+    type = 4
+    experimenter = 6035143
+    subtype = 18
+
+    def __init__(self, xid=None, enable=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if enable != None:
+            self.enable = enable
+        else:
+            self.enable = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.enable))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_bw_enable_set_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 18)
+        obj.enable = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.enable != other.enable: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_bw_enable_set_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("enable = ");
+                q.text("%#x" % self.enable)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[18] = bsn_bw_enable_set_request
+
+class bsn_get_interfaces_reply(bsn_header):
+    version = 2
+    type = 4
+    experimenter = 6035143
+    subtype = 10
+
+    def __init__(self, xid=None, interfaces=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if interfaces != None:
+            self.interfaces = interfaces
+        else:
+            self.interfaces = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.interfaces))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_get_interfaces_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 10)
+        obj.interfaces = loxi.generic_util.unpack_list(reader, ofp.common.bsn_interface.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.interfaces != other.interfaces: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_get_interfaces_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("interfaces = ");
+                q.pp(self.interfaces)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[10] = bsn_get_interfaces_reply
+
+class bsn_get_interfaces_request(bsn_header):
+    version = 2
+    type = 4
+    experimenter = 6035143
+    subtype = 9
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_get_interfaces_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 9)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_get_interfaces_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[9] = bsn_get_interfaces_request
+
+class bsn_get_mirroring_reply(bsn_header):
+    version = 2
+    type = 4
+    experimenter = 6035143
+    subtype = 5
+
+    def __init__(self, xid=None, report_mirror_ports=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if report_mirror_ports != None:
+            self.report_mirror_ports = report_mirror_ports
+        else:
+            self.report_mirror_ports = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!B", self.report_mirror_ports))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_get_mirroring_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 5)
+        obj.report_mirror_ports = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.report_mirror_ports != other.report_mirror_ports: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_get_mirroring_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("report_mirror_ports = ");
+                q.text("%#x" % self.report_mirror_ports)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[5] = bsn_get_mirroring_reply
+
+class bsn_get_mirroring_request(bsn_header):
+    version = 2
+    type = 4
+    experimenter = 6035143
+    subtype = 4
+
+    def __init__(self, xid=None, report_mirror_ports=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if report_mirror_ports != None:
+            self.report_mirror_ports = report_mirror_ports
+        else:
+            self.report_mirror_ports = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!B", self.report_mirror_ports))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_get_mirroring_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 4)
+        obj.report_mirror_ports = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.report_mirror_ports != other.report_mirror_ports: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_get_mirroring_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("report_mirror_ports = ");
+                q.text("%#x" % self.report_mirror_ports)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[4] = bsn_get_mirroring_request
+
+class bsn_pdu_rx_reply(bsn_header):
+    version = 2
+    type = 4
+    experimenter = 6035143
+    subtype = 34
+
+    def __init__(self, xid=None, status=None, port_no=None, slot_num=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if slot_num != None:
+            self.slot_num = slot_num
+        else:
+            self.slot_num = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.status))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!B", self.slot_num))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_pdu_rx_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 34)
+        obj.status = reader.read("!L")[0]
+        obj.port_no = util.unpack_port_no(reader)
+        obj.slot_num = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.status != other.status: return False
+        if self.port_no != other.port_no: return False
+        if self.slot_num != other.slot_num: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_pdu_rx_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("slot_num = ");
+                q.text("%#x" % self.slot_num)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[34] = bsn_pdu_rx_reply
+
+class bsn_pdu_rx_request(bsn_header):
+    version = 2
+    type = 4
+    experimenter = 6035143
+    subtype = 33
+
+    def __init__(self, xid=None, timeout_ms=None, port_no=None, slot_num=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if timeout_ms != None:
+            self.timeout_ms = timeout_ms
+        else:
+            self.timeout_ms = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if slot_num != None:
+            self.slot_num = slot_num
+        else:
+            self.slot_num = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.timeout_ms))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!B", self.slot_num))
+        packed.append('\x00' * 3)
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_pdu_rx_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 33)
+        obj.timeout_ms = reader.read("!L")[0]
+        obj.port_no = util.unpack_port_no(reader)
+        obj.slot_num = reader.read("!B")[0]
+        reader.skip(3)
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.timeout_ms != other.timeout_ms: return False
+        if self.port_no != other.port_no: return False
+        if self.slot_num != other.slot_num: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_pdu_rx_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("timeout_ms = ");
+                q.text("%#x" % self.timeout_ms)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("slot_num = ");
+                q.text("%#x" % self.slot_num)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[33] = bsn_pdu_rx_request
+
+class bsn_pdu_rx_timeout(bsn_header):
+    version = 2
+    type = 4
+    experimenter = 6035143
+    subtype = 35
+
+    def __init__(self, xid=None, port_no=None, slot_num=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if slot_num != None:
+            self.slot_num = slot_num
+        else:
+            self.slot_num = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!B", self.slot_num))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_pdu_rx_timeout()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 35)
+        obj.port_no = util.unpack_port_no(reader)
+        obj.slot_num = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.port_no != other.port_no: return False
+        if self.slot_num != other.slot_num: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_pdu_rx_timeout {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("slot_num = ");
+                q.text("%#x" % self.slot_num)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[35] = bsn_pdu_rx_timeout
+
+class bsn_pdu_tx_reply(bsn_header):
+    version = 2
+    type = 4
+    experimenter = 6035143
+    subtype = 32
+
+    def __init__(self, xid=None, status=None, port_no=None, slot_num=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if slot_num != None:
+            self.slot_num = slot_num
+        else:
+            self.slot_num = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.status))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!B", self.slot_num))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_pdu_tx_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 32)
+        obj.status = reader.read("!L")[0]
+        obj.port_no = util.unpack_port_no(reader)
+        obj.slot_num = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.status != other.status: return False
+        if self.port_no != other.port_no: return False
+        if self.slot_num != other.slot_num: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_pdu_tx_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("slot_num = ");
+                q.text("%#x" % self.slot_num)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[32] = bsn_pdu_tx_reply
+
+class bsn_pdu_tx_request(bsn_header):
+    version = 2
+    type = 4
+    experimenter = 6035143
+    subtype = 31
+
+    def __init__(self, xid=None, tx_interval_ms=None, port_no=None, slot_num=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if tx_interval_ms != None:
+            self.tx_interval_ms = tx_interval_ms
+        else:
+            self.tx_interval_ms = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if slot_num != None:
+            self.slot_num = slot_num
+        else:
+            self.slot_num = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.tx_interval_ms))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!B", self.slot_num))
+        packed.append('\x00' * 3)
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_pdu_tx_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 31)
+        obj.tx_interval_ms = reader.read("!L")[0]
+        obj.port_no = util.unpack_port_no(reader)
+        obj.slot_num = reader.read("!B")[0]
+        reader.skip(3)
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.tx_interval_ms != other.tx_interval_ms: return False
+        if self.port_no != other.port_no: return False
+        if self.slot_num != other.slot_num: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_pdu_tx_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("tx_interval_ms = ");
+                q.text("%#x" % self.tx_interval_ms)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("slot_num = ");
+                q.text("%#x" % self.slot_num)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[31] = bsn_pdu_tx_request
+
+class bsn_set_mirroring(bsn_header):
+    version = 2
+    type = 4
+    experimenter = 6035143
+    subtype = 3
+
+    def __init__(self, xid=None, report_mirror_ports=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if report_mirror_ports != None:
+            self.report_mirror_ports = report_mirror_ports
+        else:
+            self.report_mirror_ports = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!B", self.report_mirror_ports))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_mirroring()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 3)
+        obj.report_mirror_ports = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.report_mirror_ports != other.report_mirror_ports: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_mirroring {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("report_mirror_ports = ");
+                q.text("%#x" % self.report_mirror_ports)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[3] = bsn_set_mirroring
+
+class bsn_set_pktin_suppression_reply(bsn_header):
+    version = 2
+    type = 4
+    experimenter = 6035143
+    subtype = 25
+
+    def __init__(self, xid=None, status=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.status))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_pktin_suppression_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 25)
+        obj.status = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.status != other.status: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_pktin_suppression_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[25] = bsn_set_pktin_suppression_reply
+
+class bsn_set_pktin_suppression_request(bsn_header):
+    version = 2
+    type = 4
+    experimenter = 6035143
+    subtype = 11
+
+    def __init__(self, xid=None, enabled=None, idle_timeout=None, hard_timeout=None, priority=None, cookie=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if enabled != None:
+            self.enabled = enabled
+        else:
+            self.enabled = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!B", self.enabled))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!Q", self.cookie))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_pktin_suppression_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 11)
+        obj.enabled = reader.read("!B")[0]
+        reader.skip(1)
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.cookie = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.enabled != other.enabled: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.priority != other.priority: return False
+        if self.cookie != other.cookie: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_pktin_suppression_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("enabled = ");
+                q.text("%#x" % self.enabled)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[11] = bsn_set_pktin_suppression_request
+
+class experimenter_stats_reply(stats_reply):
+    subtypes = {}
+
+    version = 2
+    type = 19
+    stats_type = 65535
+
+    def __init__(self, xid=None, flags=None, experimenter=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append('\x00' * 4)
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 16)
+        subclass = experimenter_stats_reply.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = experimenter_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.experimenter = reader.read("!L")[0]
+        reader.skip(4)
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.experimenter != other.experimenter: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[65535] = experimenter_stats_reply
+
+class bsn_stats_reply(experimenter_stats_reply):
+    subtypes = {}
+
+    version = 2
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+
+    def __init__(self, xid=None, flags=None, subtype=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 20)
+        subclass = bsn_stats_reply.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = bsn_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        obj.subtype = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+experimenter_stats_reply.subtypes[6035143] = bsn_stats_reply
+
+class experimenter_stats_request(stats_request):
+    subtypes = {}
+
+    version = 2
+    type = 18
+    stats_type = 65535
+
+    def __init__(self, xid=None, flags=None, experimenter=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append('\x00' * 4)
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 16)
+        subclass = experimenter_stats_request.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = experimenter_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.experimenter = reader.read("!L")[0]
+        reader.skip(4)
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.experimenter != other.experimenter: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[65535] = experimenter_stats_request
+
+class bsn_stats_request(experimenter_stats_request):
+    subtypes = {}
+
+    version = 2
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+
+    def __init__(self, xid=None, flags=None, subtype=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 20)
+        subclass = bsn_stats_request.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = bsn_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        obj.subtype = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+experimenter_stats_request.subtypes[6035143] = bsn_stats_request
+
+class bsn_virtual_port_create_reply(bsn_header):
+    version = 2
+    type = 4
+    experimenter = 6035143
+    subtype = 16
+
+    def __init__(self, xid=None, status=None, vport_no=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        if vport_no != None:
+            self.vport_no = vport_no
+        else:
+            self.vport_no = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.status))
+        packed.append(struct.pack("!L", self.vport_no))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_virtual_port_create_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 16)
+        obj.status = reader.read("!L")[0]
+        obj.vport_no = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.status != other.status: return False
+        if self.vport_no != other.vport_no: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_virtual_port_create_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+                q.text(","); q.breakable()
+                q.text("vport_no = ");
+                q.text("%#x" % self.vport_no)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[16] = bsn_virtual_port_create_reply
+
+class bsn_virtual_port_create_request(bsn_header):
+    version = 2
+    type = 4
+    experimenter = 6035143
+    subtype = 15
+
+    def __init__(self, xid=None, vport=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if vport != None:
+            self.vport = vport
+        else:
+            self.vport = ofp.bsn_vport()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(self.vport.pack())
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_virtual_port_create_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 15)
+        obj.vport = ofp.bsn_vport.unpack(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.vport != other.vport: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_virtual_port_create_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("vport = ");
+                q.pp(self.vport)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[15] = bsn_virtual_port_create_request
+
+class bsn_virtual_port_remove_reply(bsn_header):
+    version = 2
+    type = 4
+    experimenter = 6035143
+    subtype = 26
+
+    def __init__(self, xid=None, status=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.status))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_virtual_port_remove_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 26)
+        obj.status = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.status != other.status: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_virtual_port_remove_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[26] = bsn_virtual_port_remove_reply
+
+class bsn_virtual_port_remove_request(bsn_header):
+    version = 2
+    type = 4
+    experimenter = 6035143
+    subtype = 17
+
+    def __init__(self, xid=None, vport_no=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if vport_no != None:
+            self.vport_no = vport_no
+        else:
+            self.vport_no = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.vport_no))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_virtual_port_remove_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 17)
+        obj.vport_no = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.vport_no != other.vport_no: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_virtual_port_remove_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("vport_no = ");
+                q.text("%#x" % self.vport_no)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[17] = bsn_virtual_port_remove_request
+
+class desc_stats_reply(stats_reply):
+    version = 2
+    type = 19
+    stats_type = 0
+
+    def __init__(self, xid=None, flags=None, mfr_desc=None, hw_desc=None, sw_desc=None, serial_num=None, dp_desc=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if mfr_desc != None:
+            self.mfr_desc = mfr_desc
+        else:
+            self.mfr_desc = ""
+        if hw_desc != None:
+            self.hw_desc = hw_desc
+        else:
+            self.hw_desc = ""
+        if sw_desc != None:
+            self.sw_desc = sw_desc
+        else:
+            self.sw_desc = ""
+        if serial_num != None:
+            self.serial_num = serial_num
+        else:
+            self.serial_num = ""
+        if dp_desc != None:
+            self.dp_desc = dp_desc
+        else:
+            self.dp_desc = ""
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!256s", self.mfr_desc))
+        packed.append(struct.pack("!256s", self.hw_desc))
+        packed.append(struct.pack("!256s", self.sw_desc))
+        packed.append(struct.pack("!32s", self.serial_num))
+        packed.append(struct.pack("!256s", self.dp_desc))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = desc_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 0)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.mfr_desc = reader.read("!256s")[0].rstrip("\x00")
+        obj.hw_desc = reader.read("!256s")[0].rstrip("\x00")
+        obj.sw_desc = reader.read("!256s")[0].rstrip("\x00")
+        obj.serial_num = reader.read("!32s")[0].rstrip("\x00")
+        obj.dp_desc = reader.read("!256s")[0].rstrip("\x00")
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.mfr_desc != other.mfr_desc: return False
+        if self.hw_desc != other.hw_desc: return False
+        if self.sw_desc != other.sw_desc: return False
+        if self.serial_num != other.serial_num: return False
+        if self.dp_desc != other.dp_desc: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("desc_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("mfr_desc = ");
+                q.pp(self.mfr_desc)
+                q.text(","); q.breakable()
+                q.text("hw_desc = ");
+                q.pp(self.hw_desc)
+                q.text(","); q.breakable()
+                q.text("sw_desc = ");
+                q.pp(self.sw_desc)
+                q.text(","); q.breakable()
+                q.text("serial_num = ");
+                q.pp(self.serial_num)
+                q.text(","); q.breakable()
+                q.text("dp_desc = ");
+                q.pp(self.dp_desc)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[0] = desc_stats_reply
+
+class desc_stats_request(stats_request):
+    version = 2
+    type = 18
+    stats_type = 0
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = desc_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 0)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("desc_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[0] = desc_stats_request
+
+class echo_reply(message):
+    version = 2
+    type = 3
+
+    def __init__(self, xid=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = echo_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 3)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("echo_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[3] = echo_reply
+
+class echo_request(message):
+    version = 2
+    type = 2
+
+    def __init__(self, xid=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = echo_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 2)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("echo_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[2] = echo_request
+
+class features_reply(message):
+    version = 2
+    type = 6
+
+    def __init__(self, xid=None, datapath_id=None, n_buffers=None, n_tables=None, capabilities=None, reserved=None, ports=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if datapath_id != None:
+            self.datapath_id = datapath_id
+        else:
+            self.datapath_id = 0
+        if n_buffers != None:
+            self.n_buffers = n_buffers
+        else:
+            self.n_buffers = 0
+        if n_tables != None:
+            self.n_tables = n_tables
+        else:
+            self.n_tables = 0
+        if capabilities != None:
+            self.capabilities = capabilities
+        else:
+            self.capabilities = 0
+        if reserved != None:
+            self.reserved = reserved
+        else:
+            self.reserved = 0
+        if ports != None:
+            self.ports = ports
+        else:
+            self.ports = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!Q", self.datapath_id))
+        packed.append(struct.pack("!L", self.n_buffers))
+        packed.append(struct.pack("!B", self.n_tables))
+        packed.append('\x00' * 3)
+        packed.append(struct.pack("!L", self.capabilities))
+        packed.append(struct.pack("!L", self.reserved))
+        packed.append(loxi.generic_util.pack_list(self.ports))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = features_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 6)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.datapath_id = reader.read("!Q")[0]
+        obj.n_buffers = reader.read("!L")[0]
+        obj.n_tables = reader.read("!B")[0]
+        reader.skip(3)
+        obj.capabilities = reader.read("!L")[0]
+        obj.reserved = reader.read("!L")[0]
+        obj.ports = loxi.generic_util.unpack_list(reader, ofp.common.port_desc.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.datapath_id != other.datapath_id: return False
+        if self.n_buffers != other.n_buffers: return False
+        if self.n_tables != other.n_tables: return False
+        if self.capabilities != other.capabilities: return False
+        if self.reserved != other.reserved: return False
+        if self.ports != other.ports: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("features_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("datapath_id = ");
+                q.text("%#x" % self.datapath_id)
+                q.text(","); q.breakable()
+                q.text("n_buffers = ");
+                q.text("%#x" % self.n_buffers)
+                q.text(","); q.breakable()
+                q.text("n_tables = ");
+                q.text("%#x" % self.n_tables)
+                q.text(","); q.breakable()
+                q.text("capabilities = ");
+                q.text("%#x" % self.capabilities)
+                q.text(","); q.breakable()
+                q.text("reserved = ");
+                q.text("%#x" % self.reserved)
+                q.text(","); q.breakable()
+                q.text("ports = ");
+                q.pp(self.ports)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[6] = features_reply
+
+class features_request(message):
+    version = 2
+    type = 5
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = features_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 5)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("features_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+message.subtypes[5] = features_request
+
+class flow_mod(message):
+    subtypes = {}
+
+    version = 2
+    type = 14
+
+    def __init__(self, xid=None, cookie=None, cookie_mask=None, table_id=None, _command=None, idle_timeout=None, hard_timeout=None, priority=None, buffer_id=None, out_port=None, out_group=None, flags=None, match=None, instructions=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if cookie_mask != None:
+            self.cookie_mask = cookie_mask
+        else:
+            self.cookie_mask = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if _command != None:
+            self._command = _command
+        else:
+            self._command = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if out_group != None:
+            self.out_group = out_group
+        else:
+            self.out_group = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if instructions != None:
+            self.instructions = instructions
+        else:
+            self.instructions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.cookie_mask))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append(util.pack_fm_cmd(self._command))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!L", self.out_group))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 2)
+        packed.append(self.match.pack())
+        packed.append(loxi.generic_util.pack_list(self.instructions))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('B', 25)
+        subclass = flow_mod.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = flow_mod()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 14)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.cookie = reader.read("!Q")[0]
+        obj.cookie_mask = reader.read("!Q")[0]
+        obj.table_id = reader.read("!B")[0]
+        obj._command = util.unpack_fm_cmd(reader)
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.out_port = util.unpack_port_no(reader)
+        obj.out_group = reader.read("!L")[0]
+        obj.flags = reader.read("!H")[0]
+        reader.skip(2)
+        obj.match = ofp.match.unpack(reader)
+        obj.instructions = loxi.generic_util.unpack_list(reader, ofp.instruction.instruction.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.cookie != other.cookie: return False
+        if self.cookie_mask != other.cookie_mask: return False
+        if self.table_id != other.table_id: return False
+        if self._command != other._command: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.priority != other.priority: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.out_port != other.out_port: return False
+        if self.out_group != other.out_group: return False
+        if self.flags != other.flags: return False
+        if self.match != other.match: return False
+        if self.instructions != other.instructions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_mod {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("cookie_mask = ");
+                q.text("%#x" % self.cookie_mask)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("out_group = ");
+                q.text("%#x" % self.out_group)
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("instructions = ");
+                q.pp(self.instructions)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[14] = flow_mod
+
+class flow_add(flow_mod):
+    version = 2
+    type = 14
+    _command = 0
+
+    def __init__(self, xid=None, cookie=None, cookie_mask=None, table_id=None, idle_timeout=None, hard_timeout=None, priority=None, buffer_id=None, out_port=None, out_group=None, flags=None, match=None, instructions=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if cookie_mask != None:
+            self.cookie_mask = cookie_mask
+        else:
+            self.cookie_mask = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if out_group != None:
+            self.out_group = out_group
+        else:
+            self.out_group = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if instructions != None:
+            self.instructions = instructions
+        else:
+            self.instructions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.cookie_mask))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append(util.pack_fm_cmd(self._command))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!L", self.out_group))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 2)
+        packed.append(self.match.pack())
+        packed.append(loxi.generic_util.pack_list(self.instructions))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_add()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 14)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.cookie = reader.read("!Q")[0]
+        obj.cookie_mask = reader.read("!Q")[0]
+        obj.table_id = reader.read("!B")[0]
+        __command = util.unpack_fm_cmd(reader)
+        assert(__command == 0)
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.out_port = util.unpack_port_no(reader)
+        obj.out_group = reader.read("!L")[0]
+        obj.flags = reader.read("!H")[0]
+        reader.skip(2)
+        obj.match = ofp.match.unpack(reader)
+        obj.instructions = loxi.generic_util.unpack_list(reader, ofp.instruction.instruction.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.cookie != other.cookie: return False
+        if self.cookie_mask != other.cookie_mask: return False
+        if self.table_id != other.table_id: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.priority != other.priority: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.out_port != other.out_port: return False
+        if self.out_group != other.out_group: return False
+        if self.flags != other.flags: return False
+        if self.match != other.match: return False
+        if self.instructions != other.instructions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_add {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("cookie_mask = ");
+                q.text("%#x" % self.cookie_mask)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("out_group = ");
+                q.text("%#x" % self.out_group)
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("instructions = ");
+                q.pp(self.instructions)
+            q.breakable()
+        q.text('}')
+
+flow_mod.subtypes[0] = flow_add
+
+class flow_delete(flow_mod):
+    version = 2
+    type = 14
+    _command = 3
+
+    def __init__(self, xid=None, cookie=None, cookie_mask=None, table_id=None, idle_timeout=None, hard_timeout=None, priority=None, buffer_id=None, out_port=None, out_group=None, flags=None, match=None, instructions=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if cookie_mask != None:
+            self.cookie_mask = cookie_mask
+        else:
+            self.cookie_mask = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if out_group != None:
+            self.out_group = out_group
+        else:
+            self.out_group = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if instructions != None:
+            self.instructions = instructions
+        else:
+            self.instructions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.cookie_mask))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append(util.pack_fm_cmd(self._command))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!L", self.out_group))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 2)
+        packed.append(self.match.pack())
+        packed.append(loxi.generic_util.pack_list(self.instructions))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_delete()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 14)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.cookie = reader.read("!Q")[0]
+        obj.cookie_mask = reader.read("!Q")[0]
+        obj.table_id = reader.read("!B")[0]
+        __command = util.unpack_fm_cmd(reader)
+        assert(__command == 3)
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.out_port = util.unpack_port_no(reader)
+        obj.out_group = reader.read("!L")[0]
+        obj.flags = reader.read("!H")[0]
+        reader.skip(2)
+        obj.match = ofp.match.unpack(reader)
+        obj.instructions = loxi.generic_util.unpack_list(reader, ofp.instruction.instruction.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.cookie != other.cookie: return False
+        if self.cookie_mask != other.cookie_mask: return False
+        if self.table_id != other.table_id: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.priority != other.priority: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.out_port != other.out_port: return False
+        if self.out_group != other.out_group: return False
+        if self.flags != other.flags: return False
+        if self.match != other.match: return False
+        if self.instructions != other.instructions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_delete {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("cookie_mask = ");
+                q.text("%#x" % self.cookie_mask)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("out_group = ");
+                q.text("%#x" % self.out_group)
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("instructions = ");
+                q.pp(self.instructions)
+            q.breakable()
+        q.text('}')
+
+flow_mod.subtypes[3] = flow_delete
+
+class flow_delete_strict(flow_mod):
+    version = 2
+    type = 14
+    _command = 4
+
+    def __init__(self, xid=None, cookie=None, cookie_mask=None, table_id=None, idle_timeout=None, hard_timeout=None, priority=None, buffer_id=None, out_port=None, out_group=None, flags=None, match=None, instructions=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if cookie_mask != None:
+            self.cookie_mask = cookie_mask
+        else:
+            self.cookie_mask = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if out_group != None:
+            self.out_group = out_group
+        else:
+            self.out_group = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if instructions != None:
+            self.instructions = instructions
+        else:
+            self.instructions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.cookie_mask))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append(util.pack_fm_cmd(self._command))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!L", self.out_group))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 2)
+        packed.append(self.match.pack())
+        packed.append(loxi.generic_util.pack_list(self.instructions))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_delete_strict()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 14)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.cookie = reader.read("!Q")[0]
+        obj.cookie_mask = reader.read("!Q")[0]
+        obj.table_id = reader.read("!B")[0]
+        __command = util.unpack_fm_cmd(reader)
+        assert(__command == 4)
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.out_port = util.unpack_port_no(reader)
+        obj.out_group = reader.read("!L")[0]
+        obj.flags = reader.read("!H")[0]
+        reader.skip(2)
+        obj.match = ofp.match.unpack(reader)
+        obj.instructions = loxi.generic_util.unpack_list(reader, ofp.instruction.instruction.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.cookie != other.cookie: return False
+        if self.cookie_mask != other.cookie_mask: return False
+        if self.table_id != other.table_id: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.priority != other.priority: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.out_port != other.out_port: return False
+        if self.out_group != other.out_group: return False
+        if self.flags != other.flags: return False
+        if self.match != other.match: return False
+        if self.instructions != other.instructions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_delete_strict {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("cookie_mask = ");
+                q.text("%#x" % self.cookie_mask)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("out_group = ");
+                q.text("%#x" % self.out_group)
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("instructions = ");
+                q.pp(self.instructions)
+            q.breakable()
+        q.text('}')
+
+flow_mod.subtypes[4] = flow_delete_strict
+
+class flow_mod_failed_error_msg(error_msg):
+    version = 2
+    type = 1
+    err_type = 5
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_mod_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 5)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_mod_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[5] = flow_mod_failed_error_msg
+
+class flow_modify(flow_mod):
+    version = 2
+    type = 14
+    _command = 1
+
+    def __init__(self, xid=None, cookie=None, cookie_mask=None, table_id=None, idle_timeout=None, hard_timeout=None, priority=None, buffer_id=None, out_port=None, out_group=None, flags=None, match=None, instructions=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if cookie_mask != None:
+            self.cookie_mask = cookie_mask
+        else:
+            self.cookie_mask = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if out_group != None:
+            self.out_group = out_group
+        else:
+            self.out_group = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if instructions != None:
+            self.instructions = instructions
+        else:
+            self.instructions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.cookie_mask))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append(util.pack_fm_cmd(self._command))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!L", self.out_group))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 2)
+        packed.append(self.match.pack())
+        packed.append(loxi.generic_util.pack_list(self.instructions))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_modify()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 14)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.cookie = reader.read("!Q")[0]
+        obj.cookie_mask = reader.read("!Q")[0]
+        obj.table_id = reader.read("!B")[0]
+        __command = util.unpack_fm_cmd(reader)
+        assert(__command == 1)
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.out_port = util.unpack_port_no(reader)
+        obj.out_group = reader.read("!L")[0]
+        obj.flags = reader.read("!H")[0]
+        reader.skip(2)
+        obj.match = ofp.match.unpack(reader)
+        obj.instructions = loxi.generic_util.unpack_list(reader, ofp.instruction.instruction.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.cookie != other.cookie: return False
+        if self.cookie_mask != other.cookie_mask: return False
+        if self.table_id != other.table_id: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.priority != other.priority: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.out_port != other.out_port: return False
+        if self.out_group != other.out_group: return False
+        if self.flags != other.flags: return False
+        if self.match != other.match: return False
+        if self.instructions != other.instructions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_modify {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("cookie_mask = ");
+                q.text("%#x" % self.cookie_mask)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("out_group = ");
+                q.text("%#x" % self.out_group)
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("instructions = ");
+                q.pp(self.instructions)
+            q.breakable()
+        q.text('}')
+
+flow_mod.subtypes[1] = flow_modify
+
+class flow_modify_strict(flow_mod):
+    version = 2
+    type = 14
+    _command = 2
+
+    def __init__(self, xid=None, cookie=None, cookie_mask=None, table_id=None, idle_timeout=None, hard_timeout=None, priority=None, buffer_id=None, out_port=None, out_group=None, flags=None, match=None, instructions=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if cookie_mask != None:
+            self.cookie_mask = cookie_mask
+        else:
+            self.cookie_mask = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if out_group != None:
+            self.out_group = out_group
+        else:
+            self.out_group = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if instructions != None:
+            self.instructions = instructions
+        else:
+            self.instructions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.cookie_mask))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append(util.pack_fm_cmd(self._command))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!L", self.out_group))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 2)
+        packed.append(self.match.pack())
+        packed.append(loxi.generic_util.pack_list(self.instructions))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_modify_strict()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 14)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.cookie = reader.read("!Q")[0]
+        obj.cookie_mask = reader.read("!Q")[0]
+        obj.table_id = reader.read("!B")[0]
+        __command = util.unpack_fm_cmd(reader)
+        assert(__command == 2)
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.out_port = util.unpack_port_no(reader)
+        obj.out_group = reader.read("!L")[0]
+        obj.flags = reader.read("!H")[0]
+        reader.skip(2)
+        obj.match = ofp.match.unpack(reader)
+        obj.instructions = loxi.generic_util.unpack_list(reader, ofp.instruction.instruction.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.cookie != other.cookie: return False
+        if self.cookie_mask != other.cookie_mask: return False
+        if self.table_id != other.table_id: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.priority != other.priority: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.out_port != other.out_port: return False
+        if self.out_group != other.out_group: return False
+        if self.flags != other.flags: return False
+        if self.match != other.match: return False
+        if self.instructions != other.instructions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_modify_strict {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("cookie_mask = ");
+                q.text("%#x" % self.cookie_mask)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("out_group = ");
+                q.text("%#x" % self.out_group)
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("instructions = ");
+                q.pp(self.instructions)
+            q.breakable()
+        q.text('}')
+
+flow_mod.subtypes[2] = flow_modify_strict
+
+class flow_removed(message):
+    version = 2
+    type = 11
+
+    def __init__(self, xid=None, cookie=None, priority=None, reason=None, table_id=None, duration_sec=None, duration_nsec=None, idle_timeout=None, packet_count=None, byte_count=None, match=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if reason != None:
+            self.reason = reason
+        else:
+            self.reason = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if duration_sec != None:
+            self.duration_sec = duration_sec
+        else:
+            self.duration_sec = 0
+        if duration_nsec != None:
+            self.duration_nsec = duration_nsec
+        else:
+            self.duration_nsec = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if packet_count != None:
+            self.packet_count = packet_count
+        else:
+            self.packet_count = 0
+        if byte_count != None:
+            self.byte_count = byte_count
+        else:
+            self.byte_count = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!B", self.reason))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append(struct.pack("!L", self.duration_sec))
+        packed.append(struct.pack("!L", self.duration_nsec))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!Q", self.packet_count))
+        packed.append(struct.pack("!Q", self.byte_count))
+        packed.append(self.match.pack())
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_removed()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 11)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.cookie = reader.read("!Q")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.reason = reader.read("!B")[0]
+        obj.table_id = reader.read("!B")[0]
+        obj.duration_sec = reader.read("!L")[0]
+        obj.duration_nsec = reader.read("!L")[0]
+        obj.idle_timeout = reader.read("!H")[0]
+        reader.skip(2)
+        obj.packet_count = reader.read("!Q")[0]
+        obj.byte_count = reader.read("!Q")[0]
+        obj.match = ofp.match.unpack(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.cookie != other.cookie: return False
+        if self.priority != other.priority: return False
+        if self.reason != other.reason: return False
+        if self.table_id != other.table_id: return False
+        if self.duration_sec != other.duration_sec: return False
+        if self.duration_nsec != other.duration_nsec: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.packet_count != other.packet_count: return False
+        if self.byte_count != other.byte_count: return False
+        if self.match != other.match: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_removed {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("reason = ");
+                q.text("%#x" % self.reason)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("duration_sec = ");
+                q.text("%#x" % self.duration_sec)
+                q.text(","); q.breakable()
+                q.text("duration_nsec = ");
+                q.text("%#x" % self.duration_nsec)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("packet_count = ");
+                q.text("%#x" % self.packet_count)
+                q.text(","); q.breakable()
+                q.text("byte_count = ");
+                q.text("%#x" % self.byte_count)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[11] = flow_removed
+
+class flow_stats_reply(stats_reply):
+    version = 2
+    type = 19
+    stats_type = 1
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 1)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.flow_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[1] = flow_stats_reply
+
+class flow_stats_request(stats_request):
+    version = 2
+    type = 18
+    stats_type = 1
+
+    def __init__(self, xid=None, flags=None, table_id=None, out_port=None, out_group=None, cookie=None, cookie_mask=None, match=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if out_group != None:
+            self.out_group = out_group
+        else:
+            self.out_group = 0
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if cookie_mask != None:
+            self.cookie_mask = cookie_mask
+        else:
+            self.cookie_mask = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append('\x00' * 3)
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!L", self.out_group))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.cookie_mask))
+        packed.append(self.match.pack())
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 1)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.table_id = reader.read("!B")[0]
+        reader.skip(3)
+        obj.out_port = util.unpack_port_no(reader)
+        obj.out_group = reader.read("!L")[0]
+        reader.skip(4)
+        obj.cookie = reader.read("!Q")[0]
+        obj.cookie_mask = reader.read("!Q")[0]
+        obj.match = ofp.match.unpack(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.table_id != other.table_id: return False
+        if self.out_port != other.out_port: return False
+        if self.out_group != other.out_group: return False
+        if self.cookie != other.cookie: return False
+        if self.cookie_mask != other.cookie_mask: return False
+        if self.match != other.match: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("out_group = ");
+                q.text("%#x" % self.out_group)
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("cookie_mask = ");
+                q.text("%#x" % self.cookie_mask)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[1] = flow_stats_request
+
+class get_config_reply(message):
+    version = 2
+    type = 8
+
+    def __init__(self, xid=None, flags=None, miss_send_len=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if miss_send_len != None:
+            self.miss_send_len = miss_send_len
+        else:
+            self.miss_send_len = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(struct.pack("!H", self.miss_send_len))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = get_config_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 8)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.flags = reader.read("!H")[0]
+        obj.miss_send_len = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.miss_send_len != other.miss_send_len: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("get_config_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("miss_send_len = ");
+                q.text("%#x" % self.miss_send_len)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[8] = get_config_reply
+
+class get_config_request(message):
+    version = 2
+    type = 7
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = get_config_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 7)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("get_config_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+message.subtypes[7] = get_config_request
+
+class group_mod(message):
+    subtypes = {}
+
+    version = 2
+    type = 15
+
+    def __init__(self, xid=None, command=None, group_type=None, group_id=None, buckets=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if command != None:
+            self.command = command
+        else:
+            self.command = 0
+        if group_type != None:
+            self.group_type = group_type
+        else:
+            self.group_type = 0
+        if group_id != None:
+            self.group_id = group_id
+        else:
+            self.group_id = 0
+        if buckets != None:
+            self.buckets = buckets
+        else:
+            self.buckets = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.command))
+        packed.append(struct.pack("!B", self.group_type))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!L", self.group_id))
+        packed.append(loxi.generic_util.pack_list(self.buckets))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 8)
+        subclass = group_mod.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = group_mod()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 15)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.command = reader.read("!H")[0]
+        obj.group_type = reader.read("!B")[0]
+        reader.skip(1)
+        obj.group_id = reader.read("!L")[0]
+        obj.buckets = loxi.generic_util.unpack_list(reader, ofp.common.bucket.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.command != other.command: return False
+        if self.group_type != other.group_type: return False
+        if self.group_id != other.group_id: return False
+        if self.buckets != other.buckets: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_mod {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("group_type = ");
+                q.text("%#x" % self.group_type)
+                q.text(","); q.breakable()
+                q.text("group_id = ");
+                q.text("%#x" % self.group_id)
+                q.text(","); q.breakable()
+                q.text("buckets = ");
+                q.pp(self.buckets)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[15] = group_mod
+
+class group_add(group_mod):
+    version = 2
+    type = 15
+    command = 0
+
+    def __init__(self, xid=None, group_type=None, group_id=None, buckets=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if group_type != None:
+            self.group_type = group_type
+        else:
+            self.group_type = 0
+        if group_id != None:
+            self.group_id = group_id
+        else:
+            self.group_id = 0
+        if buckets != None:
+            self.buckets = buckets
+        else:
+            self.buckets = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.command))
+        packed.append(struct.pack("!B", self.group_type))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!L", self.group_id))
+        packed.append(loxi.generic_util.pack_list(self.buckets))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_add()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 15)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _command = reader.read("!H")[0]
+        assert(_command == 0)
+        obj.group_type = reader.read("!B")[0]
+        reader.skip(1)
+        obj.group_id = reader.read("!L")[0]
+        obj.buckets = loxi.generic_util.unpack_list(reader, ofp.common.bucket.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.group_type != other.group_type: return False
+        if self.group_id != other.group_id: return False
+        if self.buckets != other.buckets: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_add {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("group_type = ");
+                q.text("%#x" % self.group_type)
+                q.text(","); q.breakable()
+                q.text("group_id = ");
+                q.text("%#x" % self.group_id)
+                q.text(","); q.breakable()
+                q.text("buckets = ");
+                q.pp(self.buckets)
+            q.breakable()
+        q.text('}')
+
+group_mod.subtypes[0] = group_add
+
+class group_delete(group_mod):
+    version = 2
+    type = 15
+    command = 2
+
+    def __init__(self, xid=None, group_type=None, group_id=None, buckets=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if group_type != None:
+            self.group_type = group_type
+        else:
+            self.group_type = 0
+        if group_id != None:
+            self.group_id = group_id
+        else:
+            self.group_id = 0
+        if buckets != None:
+            self.buckets = buckets
+        else:
+            self.buckets = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.command))
+        packed.append(struct.pack("!B", self.group_type))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!L", self.group_id))
+        packed.append(loxi.generic_util.pack_list(self.buckets))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_delete()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 15)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _command = reader.read("!H")[0]
+        assert(_command == 2)
+        obj.group_type = reader.read("!B")[0]
+        reader.skip(1)
+        obj.group_id = reader.read("!L")[0]
+        obj.buckets = loxi.generic_util.unpack_list(reader, ofp.common.bucket.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.group_type != other.group_type: return False
+        if self.group_id != other.group_id: return False
+        if self.buckets != other.buckets: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_delete {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("group_type = ");
+                q.text("%#x" % self.group_type)
+                q.text(","); q.breakable()
+                q.text("group_id = ");
+                q.text("%#x" % self.group_id)
+                q.text(","); q.breakable()
+                q.text("buckets = ");
+                q.pp(self.buckets)
+            q.breakable()
+        q.text('}')
+
+group_mod.subtypes[2] = group_delete
+
+class group_desc_stats_reply(stats_reply):
+    version = 2
+    type = 19
+    stats_type = 7
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_desc_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 7)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.group_desc_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_desc_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[7] = group_desc_stats_reply
+
+class group_desc_stats_request(stats_request):
+    version = 2
+    type = 18
+    stats_type = 7
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_desc_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 7)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_desc_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[7] = group_desc_stats_request
+
+class group_mod_failed_error_msg(error_msg):
+    version = 2
+    type = 1
+    err_type = 6
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_mod_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 6)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_mod_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[6] = group_mod_failed_error_msg
+
+class group_modify(group_mod):
+    version = 2
+    type = 15
+    command = 1
+
+    def __init__(self, xid=None, group_type=None, group_id=None, buckets=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if group_type != None:
+            self.group_type = group_type
+        else:
+            self.group_type = 0
+        if group_id != None:
+            self.group_id = group_id
+        else:
+            self.group_id = 0
+        if buckets != None:
+            self.buckets = buckets
+        else:
+            self.buckets = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.command))
+        packed.append(struct.pack("!B", self.group_type))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!L", self.group_id))
+        packed.append(loxi.generic_util.pack_list(self.buckets))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_modify()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 15)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _command = reader.read("!H")[0]
+        assert(_command == 1)
+        obj.group_type = reader.read("!B")[0]
+        reader.skip(1)
+        obj.group_id = reader.read("!L")[0]
+        obj.buckets = loxi.generic_util.unpack_list(reader, ofp.common.bucket.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.group_type != other.group_type: return False
+        if self.group_id != other.group_id: return False
+        if self.buckets != other.buckets: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_modify {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("group_type = ");
+                q.text("%#x" % self.group_type)
+                q.text(","); q.breakable()
+                q.text("group_id = ");
+                q.text("%#x" % self.group_id)
+                q.text(","); q.breakable()
+                q.text("buckets = ");
+                q.pp(self.buckets)
+            q.breakable()
+        q.text('}')
+
+group_mod.subtypes[1] = group_modify
+
+class group_stats_reply(stats_reply):
+    version = 2
+    type = 19
+    stats_type = 6
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 6)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.group_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[6] = group_stats_reply
+
+class group_stats_request(stats_request):
+    version = 2
+    type = 18
+    stats_type = 6
+
+    def __init__(self, xid=None, flags=None, group_id=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if group_id != None:
+            self.group_id = group_id
+        else:
+            self.group_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.group_id))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 6)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.group_id = reader.read("!L")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.group_id != other.group_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("group_id = ");
+                q.text("%#x" % self.group_id)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[6] = group_stats_request
+
+class hello(message):
+    version = 2
+    type = 0
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = hello()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 0)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("hello {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+message.subtypes[0] = hello
+
+class hello_failed_error_msg(error_msg):
+    version = 2
+    type = 1
+    err_type = 0
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = hello_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 0)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("hello_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[0] = hello_failed_error_msg
+
+class nicira_header(experimenter):
+    subtypes = {}
+
+    version = 2
+    type = 4
+    experimenter = 8992
+
+    def __init__(self, xid=None, subtype=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 12)
+        subclass = nicira_header.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = nicira_header()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 8992)
+        obj.subtype = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("nicira_header {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+experimenter.subtypes[8992] = nicira_header
+
+class packet_in(message):
+    version = 2
+    type = 10
+
+    def __init__(self, xid=None, buffer_id=None, in_port=None, in_phy_port=None, total_len=None, reason=None, table_id=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if in_port != None:
+            self.in_port = in_port
+        else:
+            self.in_port = 0
+        if in_phy_port != None:
+            self.in_phy_port = in_phy_port
+        else:
+            self.in_phy_port = 0
+        if total_len != None:
+            self.total_len = total_len
+        else:
+            self.total_len = 0
+        if reason != None:
+            self.reason = reason
+        else:
+            self.reason = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(util.pack_port_no(self.in_port))
+        packed.append(util.pack_port_no(self.in_phy_port))
+        packed.append(struct.pack("!H", self.total_len))
+        packed.append(struct.pack("!B", self.reason))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = packet_in()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 10)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.in_port = util.unpack_port_no(reader)
+        obj.in_phy_port = util.unpack_port_no(reader)
+        obj.total_len = reader.read("!H")[0]
+        obj.reason = reader.read("!B")[0]
+        obj.table_id = reader.read("!B")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.in_port != other.in_port: return False
+        if self.in_phy_port != other.in_phy_port: return False
+        if self.total_len != other.total_len: return False
+        if self.reason != other.reason: return False
+        if self.table_id != other.table_id: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("packet_in {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("in_port = ");
+                q.text(util.pretty_port(self.in_port))
+                q.text(","); q.breakable()
+                q.text("in_phy_port = ");
+                q.text(util.pretty_port(self.in_phy_port))
+                q.text(","); q.breakable()
+                q.text("total_len = ");
+                q.text("%#x" % self.total_len)
+                q.text(","); q.breakable()
+                q.text("reason = ");
+                q.text("%#x" % self.reason)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[10] = packet_in
+
+class packet_out(message):
+    version = 2
+    type = 13
+
+    def __init__(self, xid=None, buffer_id=None, in_port=None, actions=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if in_port != None:
+            self.in_port = in_port
+        else:
+            self.in_port = 0
+        if actions != None:
+            self.actions = actions
+        else:
+            self.actions = []
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(util.pack_port_no(self.in_port))
+        packed.append(struct.pack("!H", 0)) # placeholder for actions_len at index 6
+        packed.append('\x00' * 6)
+        packed.append(loxi.generic_util.pack_list(self.actions))
+        packed[6] = struct.pack("!H", len(packed[-1]))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = packet_out()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 13)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.in_port = util.unpack_port_no(reader)
+        _actions_len = reader.read("!H")[0]
+        reader.skip(6)
+        obj.actions = loxi.generic_util.unpack_list(reader.slice(_actions_len), ofp.action.action.unpack)
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.in_port != other.in_port: return False
+        if self.actions != other.actions: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("packet_out {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("in_port = ");
+                q.text(util.pretty_port(self.in_port))
+                q.text(","); q.breakable()
+                q.text("actions = ");
+                q.pp(self.actions)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[13] = packet_out
+
+class port_mod(message):
+    version = 2
+    type = 16
+
+    def __init__(self, xid=None, port_no=None, hw_addr=None, config=None, mask=None, advertise=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if hw_addr != None:
+            self.hw_addr = hw_addr
+        else:
+            self.hw_addr = [0,0,0,0,0,0]
+        if config != None:
+            self.config = config
+        else:
+            self.config = 0
+        if mask != None:
+            self.mask = mask
+        else:
+            self.mask = 0
+        if advertise != None:
+            self.advertise = advertise
+        else:
+            self.advertise = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!6B", *self.hw_addr))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!L", self.config))
+        packed.append(struct.pack("!L", self.mask))
+        packed.append(struct.pack("!L", self.advertise))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_mod()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 16)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.port_no = util.unpack_port_no(reader)
+        reader.skip(4)
+        obj.hw_addr = list(reader.read('!6B'))
+        reader.skip(2)
+        obj.config = reader.read("!L")[0]
+        obj.mask = reader.read("!L")[0]
+        obj.advertise = reader.read("!L")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.port_no != other.port_no: return False
+        if self.hw_addr != other.hw_addr: return False
+        if self.config != other.config: return False
+        if self.mask != other.mask: return False
+        if self.advertise != other.advertise: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_mod {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("hw_addr = ");
+                q.text(util.pretty_mac(self.hw_addr))
+                q.text(","); q.breakable()
+                q.text("config = ");
+                q.text("%#x" % self.config)
+                q.text(","); q.breakable()
+                q.text("mask = ");
+                q.text("%#x" % self.mask)
+                q.text(","); q.breakable()
+                q.text("advertise = ");
+                q.text("%#x" % self.advertise)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[16] = port_mod
+
+class port_mod_failed_error_msg(error_msg):
+    version = 2
+    type = 1
+    err_type = 7
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_mod_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 7)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_mod_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[7] = port_mod_failed_error_msg
+
+class port_stats_reply(stats_reply):
+    version = 2
+    type = 19
+    stats_type = 4
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 4)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.port_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[4] = port_stats_reply
+
+class port_stats_request(stats_request):
+    version = 2
+    type = 18
+    stats_type = 4
+
+    def __init__(self, xid=None, flags=None, port_no=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 4)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.port_no = util.unpack_port_no(reader)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.port_no != other.port_no: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[4] = port_stats_request
+
+class port_status(message):
+    version = 2
+    type = 12
+
+    def __init__(self, xid=None, reason=None, desc=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if reason != None:
+            self.reason = reason
+        else:
+            self.reason = 0
+        if desc != None:
+            self.desc = desc
+        else:
+            self.desc = ofp.port_desc()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!B", self.reason))
+        packed.append('\x00' * 7)
+        packed.append(self.desc.pack())
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_status()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 12)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.reason = reader.read("!B")[0]
+        reader.skip(7)
+        obj.desc = ofp.port_desc.unpack(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.reason != other.reason: return False
+        if self.desc != other.desc: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_status {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("reason = ");
+                q.text("%#x" % self.reason)
+                q.text(","); q.breakable()
+                q.text("desc = ");
+                q.pp(self.desc)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[12] = port_status
+
+class queue_get_config_reply(message):
+    version = 2
+    type = 23
+
+    def __init__(self, xid=None, port=None, queues=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if port != None:
+            self.port = port
+        else:
+            self.port = 0
+        if queues != None:
+            self.queues = queues
+        else:
+            self.queues = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(util.pack_port_no(self.port))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.queues))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_get_config_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 23)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.port = util.unpack_port_no(reader)
+        reader.skip(4)
+        obj.queues = loxi.generic_util.unpack_list(reader, ofp.common.packet_queue.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.port != other.port: return False
+        if self.queues != other.queues: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_get_config_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("port = ");
+                q.text(util.pretty_port(self.port))
+                q.text(","); q.breakable()
+                q.text("queues = ");
+                q.pp(self.queues)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[23] = queue_get_config_reply
+
+class queue_get_config_request(message):
+    version = 2
+    type = 22
+
+    def __init__(self, xid=None, port=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if port != None:
+            self.port = port
+        else:
+            self.port = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(util.pack_port_no(self.port))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_get_config_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 22)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.port = util.unpack_port_no(reader)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.port != other.port: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_get_config_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("port = ");
+                q.text(util.pretty_port(self.port))
+            q.breakable()
+        q.text('}')
+
+message.subtypes[22] = queue_get_config_request
+
+class queue_op_failed_error_msg(error_msg):
+    version = 2
+    type = 1
+    err_type = 9
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_op_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 9)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_op_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[9] = queue_op_failed_error_msg
+
+class queue_stats_reply(stats_reply):
+    version = 2
+    type = 19
+    stats_type = 5
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 5)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.queue_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[5] = queue_stats_reply
+
+class queue_stats_request(stats_request):
+    version = 2
+    type = 18
+    stats_type = 5
+
+    def __init__(self, xid=None, flags=None, port_no=None, queue_id=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if queue_id != None:
+            self.queue_id = queue_id
+        else:
+            self.queue_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!L", self.queue_id))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 5)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.port_no = util.unpack_port_no(reader)
+        obj.queue_id = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.port_no != other.port_no: return False
+        if self.queue_id != other.queue_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("queue_id = ");
+                q.text("%#x" % self.queue_id)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[5] = queue_stats_request
+
+class set_config(message):
+    version = 2
+    type = 9
+
+    def __init__(self, xid=None, flags=None, miss_send_len=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if miss_send_len != None:
+            self.miss_send_len = miss_send_len
+        else:
+            self.miss_send_len = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(struct.pack("!H", self.miss_send_len))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_config()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 9)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.flags = reader.read("!H")[0]
+        obj.miss_send_len = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.miss_send_len != other.miss_send_len: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_config {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("miss_send_len = ");
+                q.text("%#x" % self.miss_send_len)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[9] = set_config
+
+class switch_config_failed_error_msg(error_msg):
+    version = 2
+    type = 1
+    err_type = 10
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = switch_config_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 10)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("switch_config_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[10] = switch_config_failed_error_msg
+
+class table_mod(message):
+    version = 2
+    type = 17
+
+    def __init__(self, xid=None, table_id=None, config=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if config != None:
+            self.config = config
+        else:
+            self.config = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append('\x00' * 3)
+        packed.append(struct.pack("!L", self.config))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_mod()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 17)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.table_id = reader.read("!B")[0]
+        reader.skip(3)
+        obj.config = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.table_id != other.table_id: return False
+        if self.config != other.config: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_mod {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("config = ");
+                q.text("%#x" % self.config)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[17] = table_mod
+
+class table_mod_failed_error_msg(error_msg):
+    version = 2
+    type = 1
+    err_type = 8
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_mod_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 8)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_mod_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[8] = table_mod_failed_error_msg
+
+class table_stats_reply(stats_reply):
+    version = 2
+    type = 19
+    stats_type = 3
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 3)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.table_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[3] = table_stats_reply
+
+class table_stats_request(stats_request):
+    version = 2
+    type = 18
+    stats_type = 3
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 2)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 3)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[3] = table_stats_request
+
+
+def parse_header(buf):
+    if len(buf) < 8:
+        raise loxi.ProtocolError("too short to be an OpenFlow message")
+    return struct.unpack_from("!BBHL", buf)
+
+def parse_message(buf):
+    msg_ver, msg_type, msg_len, msg_xid = parse_header(buf)
+    if msg_ver != ofp.OFP_VERSION and msg_type != ofp.OFPT_HELLO:
+        raise loxi.ProtocolError("wrong OpenFlow version (expected %d, got %d)" % (ofp.OFP_VERSION, msg_ver))
+    if len(buf) != msg_len:
+        raise loxi.ProtocolError("incorrect message size")
+    return message.unpack(loxi.generic_util.OFReader(buf))
diff --git a/Fabric/Utilities/src/python/loxi/of11/util.py b/Fabric/Utilities/src/python/loxi/of11/util.py
new file mode 100644
index 0000000..b5142a8
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of11/util.py
@@ -0,0 +1,143 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+# Automatically generated by LOXI from template util.py
+# Do not modify
+
+import struct
+import loxi
+import const
+import common
+import action
+import instruction
+
+def pretty_mac(mac):
+    return ':'.join(["%02x" % x for x in mac])
+
+def pretty_ipv4(v):
+    return "%d.%d.%d.%d" % ((v >> 24) & 0xFF, (v >> 16) & 0xFF, (v >> 8) & 0xFF, v & 0xFF)
+
+def pretty_flags(v, flag_names):
+    set_flags = []
+    for flag_name in flag_names:
+        flag_value = getattr(const, flag_name)
+        if v & flag_value == flag_value:
+            set_flags.append(flag_name)
+        elif v & flag_value:
+            set_flags.append('%s&%#x' % (flag_name, v & flag_value))
+        v &= ~flag_value
+    if v:
+        set_flags.append("%#x" % v)
+    return '|'.join(set_flags) or '0'
+
+def pretty_wildcards(v):
+    if v == const.OFPFW_ALL:
+        return 'OFPFW_ALL'
+    flag_names = ['OFPFW_IN_PORT', 'OFPFW_DL_VLAN', 'OFPFW_DL_SRC', 'OFPFW_DL_DST',
+                  'OFPFW_DL_TYPE', 'OFPFW_NW_PROTO', 'OFPFW_TP_SRC', 'OFPFW_TP_DST',
+                  'OFPFW_NW_SRC_MASK', 'OFPFW_NW_DST_MASK', 'OFPFW_DL_VLAN_PCP',
+                  'OFPFW_NW_TOS']
+    return pretty_flags(v, flag_names)
+
+def pretty_port(v):
+    named_ports = [(k,v2) for (k,v2) in const.__dict__.iteritems() if k.startswith('OFPP_')]
+    for (k, v2) in named_ports:
+        if v == v2:
+            return k
+    return v
+
+def pack_port_no(value):
+    return struct.pack("!L", value)
+
+def unpack_port_no(reader):
+    return reader.read("!L")[0]
+
+def pack_fm_cmd(value):
+    return struct.pack("!B", value)
+
+def unpack_fm_cmd(reader):
+    return reader.read("!B")[0]
+
+def init_wc_bmap():
+    return const.OFPFW_ALL
+
+def pack_wc_bmap(value):
+    return struct.pack("!L", value)
+
+def unpack_wc_bmap(reader):
+    return reader.read("!L")[0]
+
+def init_match_bmap():
+    return const.OFPFW_ALL
+
+def pack_match_bmap(value):
+    return struct.pack("!L", value)
+
+def unpack_match_bmap(reader):
+    return reader.read("!L")[0]
+
+MASK64 = (1 << 64) - 1
+
+def pack_bitmap_128(value):
+    x = 0l
+    for y in value:
+        x |= 1 << y
+    return struct.pack("!QQ", (x >> 64) & MASK64, x & MASK64)
+
+def unpack_bitmap_128(reader):
+    hi, lo = reader.read("!QQ")
+    x = (hi << 64) | lo
+    i = 0
+    value = set()
+    while x != 0:
+        if x & 1 == 1:
+            value.add(i)
+        i += 1
+        x >>= 1
+    return value
+
+def pack_bitmap_512(value):
+    words = [0] * 8
+    for v in value:
+        assert v < 512
+        words[7-v/64] |= 1 << (v % 64)
+    return struct.pack("!8Q", *words)
+
+def unpack_bitmap_512(reader):
+    words = reader.read("!8Q")
+    x = 0l
+    for word in words:
+        x <<= 64
+        x |= word
+    i = 0
+    value = set()
+    while x != 0:
+        if x & 1 == 1:
+            value.add(i)
+        i += 1
+        x >>= 1
+    return value
+
+def pack_checksum_128(value):
+    return struct.pack("!QQ", (value >> 64) & MASK64, value & MASK64)
+
+def unpack_checksum_128(reader):
+    hi, lo = reader.read("!QQ")
+    return (hi << 64) | lo
diff --git a/Fabric/Utilities/src/python/loxi/of12/__init__.py b/Fabric/Utilities/src/python/loxi/of12/__init__.py
new file mode 100644
index 0000000..a994272
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of12/__init__.py
@@ -0,0 +1,33 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template init.py
+# Do not modify
+
+import const
+import action
+import oxm
+import message
+import instruction
+import common
+from const import *
+from common import *
+from loxi import ProtocolError
diff --git a/Fabric/Utilities/src/python/loxi/of12/action.py b/Fabric/Utilities/src/python/loxi/of12/action.py
new file mode 100644
index 0000000..261170a
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of12/action.py
@@ -0,0 +1,1147 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of12']
+
+class action(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = action.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = action()
+        obj.type = reader.read("!H")[0]
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("action {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class experimenter(action):
+    subtypes = {}
+
+    type = 65535
+
+    def __init__(self, experimenter=None, data=None):
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed.append(loxi.generic_util.pad_to(8, length))
+        length += len(packed[-1])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 4)
+        subclass = experimenter.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = experimenter()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.experimenter = reader.read("!L")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.experimenter != other.experimenter: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[65535] = experimenter
+
+class bsn(experimenter):
+    subtypes = {}
+
+    type = 65535
+    experimenter = 6035143
+
+    def __init__(self, subtype=None):
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 8)
+        subclass = bsn.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = bsn()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        obj.subtype = reader.read("!L")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+experimenter.subtypes[6035143] = bsn
+
+class bsn_checksum(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 4
+
+    def __init__(self, checksum=None):
+        if checksum != None:
+            self.checksum = checksum
+        else:
+            self.checksum = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(util.pack_checksum_128(self.checksum))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_checksum()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 4)
+        obj.checksum = util.unpack_checksum_128(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.checksum != other.checksum: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_checksum {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("checksum = ");
+                q.pp(self.checksum)
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[4] = bsn_checksum
+
+class bsn_mirror(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 1
+
+    def __init__(self, dest_port=None, vlan_tag=None, copy_stage=None):
+        if dest_port != None:
+            self.dest_port = dest_port
+        else:
+            self.dest_port = 0
+        if vlan_tag != None:
+            self.vlan_tag = vlan_tag
+        else:
+            self.vlan_tag = 0
+        if copy_stage != None:
+            self.copy_stage = copy_stage
+        else:
+            self.copy_stage = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.dest_port))
+        packed.append(struct.pack("!L", self.vlan_tag))
+        packed.append(struct.pack("!B", self.copy_stage))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_mirror()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 1)
+        obj.dest_port = reader.read("!L")[0]
+        obj.vlan_tag = reader.read("!L")[0]
+        obj.copy_stage = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.dest_port != other.dest_port: return False
+        if self.vlan_tag != other.vlan_tag: return False
+        if self.copy_stage != other.copy_stage: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_mirror {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("dest_port = ");
+                q.text("%#x" % self.dest_port)
+                q.text(","); q.breakable()
+                q.text("vlan_tag = ");
+                q.text("%#x" % self.vlan_tag)
+                q.text(","); q.breakable()
+                q.text("copy_stage = ");
+                q.text("%#x" % self.copy_stage)
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[1] = bsn_mirror
+
+class bsn_set_tunnel_dst(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 2
+
+    def __init__(self, dst=None):
+        if dst != None:
+            self.dst = dst
+        else:
+            self.dst = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.dst))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_tunnel_dst()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 2)
+        obj.dst = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.dst != other.dst: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_tunnel_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("dst = ");
+                q.text("%#x" % self.dst)
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[2] = bsn_set_tunnel_dst
+
+class copy_ttl_in(action):
+    type = 12
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = copy_ttl_in()
+        _type = reader.read("!H")[0]
+        assert(_type == 12)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("copy_ttl_in {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action.subtypes[12] = copy_ttl_in
+
+class copy_ttl_out(action):
+    type = 11
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = copy_ttl_out()
+        _type = reader.read("!H")[0]
+        assert(_type == 11)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("copy_ttl_out {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action.subtypes[11] = copy_ttl_out
+
+class dec_mpls_ttl(action):
+    type = 16
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = dec_mpls_ttl()
+        _type = reader.read("!H")[0]
+        assert(_type == 16)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("dec_mpls_ttl {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action.subtypes[16] = dec_mpls_ttl
+
+class dec_nw_ttl(action):
+    type = 24
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = dec_nw_ttl()
+        _type = reader.read("!H")[0]
+        assert(_type == 24)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("dec_nw_ttl {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action.subtypes[24] = dec_nw_ttl
+
+class group(action):
+    type = 22
+
+    def __init__(self, group_id=None):
+        if group_id != None:
+            self.group_id = group_id
+        else:
+            self.group_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.group_id))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group()
+        _type = reader.read("!H")[0]
+        assert(_type == 22)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.group_id = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.group_id != other.group_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("group_id = ");
+                q.text("%#x" % self.group_id)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[22] = group
+
+class nicira(experimenter):
+    subtypes = {}
+
+    type = 65535
+    experimenter = 8992
+
+    def __init__(self, subtype=None):
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!H", self.subtype))
+        packed.append('\x00' * 2)
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 8)
+        subclass = nicira.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = nicira()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 8992)
+        obj.subtype = reader.read("!H")[0]
+        reader.skip(2)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("nicira {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+experimenter.subtypes[8992] = nicira
+
+class nicira_dec_ttl(nicira):
+    type = 65535
+    experimenter = 8992
+    subtype = 18
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!H", self.subtype))
+        packed.append('\x00' * 2)
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = nicira_dec_ttl()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 8992)
+        _subtype = reader.read("!H")[0]
+        assert(_subtype == 18)
+        reader.skip(2)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("nicira_dec_ttl {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+nicira.subtypes[18] = nicira_dec_ttl
+
+class output(action):
+    type = 0
+
+    def __init__(self, port=None, max_len=None):
+        if port != None:
+            self.port = port
+        else:
+            self.port = 0
+        if max_len != None:
+            self.max_len = max_len
+        else:
+            self.max_len = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(util.pack_port_no(self.port))
+        packed.append(struct.pack("!H", self.max_len))
+        packed.append('\x00' * 6)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = output()
+        _type = reader.read("!H")[0]
+        assert(_type == 0)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.port = util.unpack_port_no(reader)
+        obj.max_len = reader.read("!H")[0]
+        reader.skip(6)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.port != other.port: return False
+        if self.max_len != other.max_len: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("output {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("port = ");
+                q.text(util.pretty_port(self.port))
+                q.text(","); q.breakable()
+                q.text("max_len = ");
+                q.text("%#x" % self.max_len)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[0] = output
+
+class pop_mpls(action):
+    type = 20
+
+    def __init__(self, ethertype=None):
+        if ethertype != None:
+            self.ethertype = ethertype
+        else:
+            self.ethertype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!H", self.ethertype))
+        packed.append('\x00' * 2)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = pop_mpls()
+        _type = reader.read("!H")[0]
+        assert(_type == 20)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.ethertype = reader.read("!H")[0]
+        reader.skip(2)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.ethertype != other.ethertype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("pop_mpls {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("ethertype = ");
+                q.text("%#x" % self.ethertype)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[20] = pop_mpls
+
+class pop_vlan(action):
+    type = 18
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = pop_vlan()
+        _type = reader.read("!H")[0]
+        assert(_type == 18)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("pop_vlan {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action.subtypes[18] = pop_vlan
+
+class push_mpls(action):
+    type = 19
+
+    def __init__(self, ethertype=None):
+        if ethertype != None:
+            self.ethertype = ethertype
+        else:
+            self.ethertype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!H", self.ethertype))
+        packed.append('\x00' * 2)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = push_mpls()
+        _type = reader.read("!H")[0]
+        assert(_type == 19)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.ethertype = reader.read("!H")[0]
+        reader.skip(2)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.ethertype != other.ethertype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("push_mpls {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("ethertype = ");
+                q.text("%#x" % self.ethertype)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[19] = push_mpls
+
+class push_vlan(action):
+    type = 17
+
+    def __init__(self, ethertype=None):
+        if ethertype != None:
+            self.ethertype = ethertype
+        else:
+            self.ethertype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!H", self.ethertype))
+        packed.append('\x00' * 2)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = push_vlan()
+        _type = reader.read("!H")[0]
+        assert(_type == 17)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.ethertype = reader.read("!H")[0]
+        reader.skip(2)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.ethertype != other.ethertype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("push_vlan {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("ethertype = ");
+                q.text("%#x" % self.ethertype)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[17] = push_vlan
+
+class set_field(action):
+    type = 25
+
+    def __init__(self, field=None):
+        if field != None:
+            self.field = field
+        else:
+            self.field = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(self.field.pack())
+        length = sum([len(x) for x in packed])
+        packed.append(loxi.generic_util.pad_to(8, length))
+        length += len(packed[-1])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_field()
+        _type = reader.read("!H")[0]
+        assert(_type == 25)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.field = ofp.oxm.oxm.unpack(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.field != other.field: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_field {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("field = ");
+                q.pp(self.field)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[25] = set_field
+
+class set_mpls_ttl(action):
+    type = 15
+
+    def __init__(self, mpls_ttl=None):
+        if mpls_ttl != None:
+            self.mpls_ttl = mpls_ttl
+        else:
+            self.mpls_ttl = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!B", self.mpls_ttl))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_mpls_ttl()
+        _type = reader.read("!H")[0]
+        assert(_type == 15)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.mpls_ttl = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.mpls_ttl != other.mpls_ttl: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_mpls_ttl {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("mpls_ttl = ");
+                q.text("%#x" % self.mpls_ttl)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[15] = set_mpls_ttl
+
+class set_nw_ttl(action):
+    type = 23
+
+    def __init__(self, nw_ttl=None):
+        if nw_ttl != None:
+            self.nw_ttl = nw_ttl
+        else:
+            self.nw_ttl = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!B", self.nw_ttl))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_nw_ttl()
+        _type = reader.read("!H")[0]
+        assert(_type == 23)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.nw_ttl = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.nw_ttl != other.nw_ttl: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_nw_ttl {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("nw_ttl = ");
+                q.text("%#x" % self.nw_ttl)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[23] = set_nw_ttl
+
+class set_queue(action):
+    type = 21
+
+    def __init__(self, queue_id=None):
+        if queue_id != None:
+            self.queue_id = queue_id
+        else:
+            self.queue_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.queue_id))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_queue()
+        _type = reader.read("!H")[0]
+        assert(_type == 21)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.queue_id = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.queue_id != other.queue_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_queue {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("queue_id = ");
+                q.text("%#x" % self.queue_id)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[21] = set_queue
+
+
diff --git a/Fabric/Utilities/src/python/loxi/of12/common.py b/Fabric/Utilities/src/python/loxi/of12/common.py
new file mode 100644
index 0000000..64e8379
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of12/common.py
@@ -0,0 +1,1711 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of12']
+
+class bsn_interface(loxi.OFObject):
+
+    def __init__(self, hw_addr=None, name=None, ipv4_addr=None, ipv4_netmask=None):
+        if hw_addr != None:
+            self.hw_addr = hw_addr
+        else:
+            self.hw_addr = [0,0,0,0,0,0]
+        if name != None:
+            self.name = name
+        else:
+            self.name = ""
+        if ipv4_addr != None:
+            self.ipv4_addr = ipv4_addr
+        else:
+            self.ipv4_addr = 0
+        if ipv4_netmask != None:
+            self.ipv4_netmask = ipv4_netmask
+        else:
+            self.ipv4_netmask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!6B", *self.hw_addr))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!16s", self.name))
+        packed.append(struct.pack("!L", self.ipv4_addr))
+        packed.append(struct.pack("!L", self.ipv4_netmask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_interface()
+        obj.hw_addr = list(reader.read('!6B'))
+        reader.skip(2)
+        obj.name = reader.read("!16s")[0].rstrip("\x00")
+        obj.ipv4_addr = reader.read("!L")[0]
+        obj.ipv4_netmask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.hw_addr != other.hw_addr: return False
+        if self.name != other.name: return False
+        if self.ipv4_addr != other.ipv4_addr: return False
+        if self.ipv4_netmask != other.ipv4_netmask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_interface {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("hw_addr = ");
+                q.text(util.pretty_mac(self.hw_addr))
+                q.text(","); q.breakable()
+                q.text("name = ");
+                q.pp(self.name)
+                q.text(","); q.breakable()
+                q.text("ipv4_addr = ");
+                q.text(util.pretty_ipv4(self.ipv4_addr))
+                q.text(","); q.breakable()
+                q.text("ipv4_netmask = ");
+                q.text(util.pretty_ipv4(self.ipv4_netmask))
+            q.breakable()
+        q.text('}')
+
+
+class bsn_vport(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = bsn_vport.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = bsn_vport()
+        obj.type = reader.read("!H")[0]
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vport {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class bsn_vport_l2gre(bsn_vport):
+    type = 1
+
+    def __init__(self, flags=None, port_no=None, loopback_port_no=None, local_mac=None, nh_mac=None, src_ip=None, dst_ip=None, dscp=None, ttl=None, vpn=None, rate_limit=None, if_name=None):
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if loopback_port_no != None:
+            self.loopback_port_no = loopback_port_no
+        else:
+            self.loopback_port_no = 0
+        if local_mac != None:
+            self.local_mac = local_mac
+        else:
+            self.local_mac = [0,0,0,0,0,0]
+        if nh_mac != None:
+            self.nh_mac = nh_mac
+        else:
+            self.nh_mac = [0,0,0,0,0,0]
+        if src_ip != None:
+            self.src_ip = src_ip
+        else:
+            self.src_ip = 0
+        if dst_ip != None:
+            self.dst_ip = dst_ip
+        else:
+            self.dst_ip = 0
+        if dscp != None:
+            self.dscp = dscp
+        else:
+            self.dscp = 0
+        if ttl != None:
+            self.ttl = ttl
+        else:
+            self.ttl = 0
+        if vpn != None:
+            self.vpn = vpn
+        else:
+            self.vpn = 0
+        if rate_limit != None:
+            self.rate_limit = rate_limit
+        else:
+            self.rate_limit = 0
+        if if_name != None:
+            self.if_name = if_name
+        else:
+            self.if_name = ""
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.flags))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(util.pack_port_no(self.loopback_port_no))
+        packed.append(struct.pack("!6B", *self.local_mac))
+        packed.append(struct.pack("!6B", *self.nh_mac))
+        packed.append(struct.pack("!L", self.src_ip))
+        packed.append(struct.pack("!L", self.dst_ip))
+        packed.append(struct.pack("!B", self.dscp))
+        packed.append(struct.pack("!B", self.ttl))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!L", self.vpn))
+        packed.append(struct.pack("!L", self.rate_limit))
+        packed.append(struct.pack("!16s", self.if_name))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vport_l2gre()
+        _type = reader.read("!H")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.flags = reader.read("!L")[0]
+        obj.port_no = util.unpack_port_no(reader)
+        obj.loopback_port_no = util.unpack_port_no(reader)
+        obj.local_mac = list(reader.read('!6B'))
+        obj.nh_mac = list(reader.read('!6B'))
+        obj.src_ip = reader.read("!L")[0]
+        obj.dst_ip = reader.read("!L")[0]
+        obj.dscp = reader.read("!B")[0]
+        obj.ttl = reader.read("!B")[0]
+        reader.skip(2)
+        obj.vpn = reader.read("!L")[0]
+        obj.rate_limit = reader.read("!L")[0]
+        obj.if_name = reader.read("!16s")[0].rstrip("\x00")
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.flags != other.flags: return False
+        if self.port_no != other.port_no: return False
+        if self.loopback_port_no != other.loopback_port_no: return False
+        if self.local_mac != other.local_mac: return False
+        if self.nh_mac != other.nh_mac: return False
+        if self.src_ip != other.src_ip: return False
+        if self.dst_ip != other.dst_ip: return False
+        if self.dscp != other.dscp: return False
+        if self.ttl != other.ttl: return False
+        if self.vpn != other.vpn: return False
+        if self.rate_limit != other.rate_limit: return False
+        if self.if_name != other.if_name: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vport_l2gre {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("loopback_port_no = ");
+                q.text(util.pretty_port(self.loopback_port_no))
+                q.text(","); q.breakable()
+                q.text("local_mac = ");
+                q.text(util.pretty_mac(self.local_mac))
+                q.text(","); q.breakable()
+                q.text("nh_mac = ");
+                q.text(util.pretty_mac(self.nh_mac))
+                q.text(","); q.breakable()
+                q.text("src_ip = ");
+                q.text(util.pretty_ipv4(self.src_ip))
+                q.text(","); q.breakable()
+                q.text("dst_ip = ");
+                q.text(util.pretty_ipv4(self.dst_ip))
+                q.text(","); q.breakable()
+                q.text("dscp = ");
+                q.text("%#x" % self.dscp)
+                q.text(","); q.breakable()
+                q.text("ttl = ");
+                q.text("%#x" % self.ttl)
+                q.text(","); q.breakable()
+                q.text("vpn = ");
+                q.text("%#x" % self.vpn)
+                q.text(","); q.breakable()
+                q.text("rate_limit = ");
+                q.text("%#x" % self.rate_limit)
+                q.text(","); q.breakable()
+                q.text("if_name = ");
+                q.pp(self.if_name)
+            q.breakable()
+        q.text('}')
+
+bsn_vport.subtypes[1] = bsn_vport_l2gre
+
+class bsn_vport_q_in_q(bsn_vport):
+    type = 0
+
+    def __init__(self, port_no=None, ingress_tpid=None, ingress_vlan_id=None, egress_tpid=None, egress_vlan_id=None, if_name=None):
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if ingress_tpid != None:
+            self.ingress_tpid = ingress_tpid
+        else:
+            self.ingress_tpid = 0
+        if ingress_vlan_id != None:
+            self.ingress_vlan_id = ingress_vlan_id
+        else:
+            self.ingress_vlan_id = 0
+        if egress_tpid != None:
+            self.egress_tpid = egress_tpid
+        else:
+            self.egress_tpid = 0
+        if egress_vlan_id != None:
+            self.egress_vlan_id = egress_vlan_id
+        else:
+            self.egress_vlan_id = 0
+        if if_name != None:
+            self.if_name = if_name
+        else:
+            self.if_name = ""
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.port_no))
+        packed.append(struct.pack("!H", self.ingress_tpid))
+        packed.append(struct.pack("!H", self.ingress_vlan_id))
+        packed.append(struct.pack("!H", self.egress_tpid))
+        packed.append(struct.pack("!H", self.egress_vlan_id))
+        packed.append(struct.pack("!16s", self.if_name))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vport_q_in_q()
+        _type = reader.read("!H")[0]
+        assert(_type == 0)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.port_no = reader.read("!L")[0]
+        obj.ingress_tpid = reader.read("!H")[0]
+        obj.ingress_vlan_id = reader.read("!H")[0]
+        obj.egress_tpid = reader.read("!H")[0]
+        obj.egress_vlan_id = reader.read("!H")[0]
+        obj.if_name = reader.read("!16s")[0].rstrip("\x00")
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.port_no != other.port_no: return False
+        if self.ingress_tpid != other.ingress_tpid: return False
+        if self.ingress_vlan_id != other.ingress_vlan_id: return False
+        if self.egress_tpid != other.egress_tpid: return False
+        if self.egress_vlan_id != other.egress_vlan_id: return False
+        if self.if_name != other.if_name: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vport_q_in_q {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("port_no = ");
+                q.text("%#x" % self.port_no)
+                q.text(","); q.breakable()
+                q.text("ingress_tpid = ");
+                q.text("%#x" % self.ingress_tpid)
+                q.text(","); q.breakable()
+                q.text("ingress_vlan_id = ");
+                q.text("%#x" % self.ingress_vlan_id)
+                q.text(","); q.breakable()
+                q.text("egress_tpid = ");
+                q.text("%#x" % self.egress_tpid)
+                q.text(","); q.breakable()
+                q.text("egress_vlan_id = ");
+                q.text("%#x" % self.egress_vlan_id)
+                q.text(","); q.breakable()
+                q.text("if_name = ");
+                q.pp(self.if_name)
+            q.breakable()
+        q.text('}')
+
+bsn_vport.subtypes[0] = bsn_vport_q_in_q
+
+class bucket(loxi.OFObject):
+
+    def __init__(self, weight=None, watch_port=None, watch_group=None, actions=None):
+        if weight != None:
+            self.weight = weight
+        else:
+            self.weight = 0
+        if watch_port != None:
+            self.watch_port = watch_port
+        else:
+            self.watch_port = 0
+        if watch_group != None:
+            self.watch_group = watch_group
+        else:
+            self.watch_group = 0
+        if actions != None:
+            self.actions = actions
+        else:
+            self.actions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 0
+        packed.append(struct.pack("!H", self.weight))
+        packed.append(util.pack_port_no(self.watch_port))
+        packed.append(struct.pack("!L", self.watch_group))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.actions))
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bucket()
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 2)
+        obj.weight = reader.read("!H")[0]
+        obj.watch_port = util.unpack_port_no(reader)
+        obj.watch_group = reader.read("!L")[0]
+        reader.skip(4)
+        obj.actions = loxi.generic_util.unpack_list(reader, ofp.action.action.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.weight != other.weight: return False
+        if self.watch_port != other.watch_port: return False
+        if self.watch_group != other.watch_group: return False
+        if self.actions != other.actions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bucket {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("weight = ");
+                q.text("%#x" % self.weight)
+                q.text(","); q.breakable()
+                q.text("watch_port = ");
+                q.text(util.pretty_port(self.watch_port))
+                q.text(","); q.breakable()
+                q.text("watch_group = ");
+                q.text("%#x" % self.watch_group)
+                q.text(","); q.breakable()
+                q.text("actions = ");
+                q.pp(self.actions)
+            q.breakable()
+        q.text('}')
+
+
+class bucket_counter(loxi.OFObject):
+
+    def __init__(self, packet_count=None, byte_count=None):
+        if packet_count != None:
+            self.packet_count = packet_count
+        else:
+            self.packet_count = 0
+        if byte_count != None:
+            self.byte_count = byte_count
+        else:
+            self.byte_count = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!Q", self.packet_count))
+        packed.append(struct.pack("!Q", self.byte_count))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bucket_counter()
+        obj.packet_count = reader.read("!Q")[0]
+        obj.byte_count = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.packet_count != other.packet_count: return False
+        if self.byte_count != other.byte_count: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bucket_counter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("packet_count = ");
+                q.text("%#x" % self.packet_count)
+                q.text(","); q.breakable()
+                q.text("byte_count = ");
+                q.text("%#x" % self.byte_count)
+            q.breakable()
+        q.text('}')
+
+
+class flow_stats_entry(loxi.OFObject):
+
+    def __init__(self, table_id=None, duration_sec=None, duration_nsec=None, priority=None, idle_timeout=None, hard_timeout=None, cookie=None, packet_count=None, byte_count=None, match=None, instructions=None):
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if duration_sec != None:
+            self.duration_sec = duration_sec
+        else:
+            self.duration_sec = 0
+        if duration_nsec != None:
+            self.duration_nsec = duration_nsec
+        else:
+            self.duration_nsec = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if packet_count != None:
+            self.packet_count = packet_count
+        else:
+            self.packet_count = 0
+        if byte_count != None:
+            self.byte_count = byte_count
+        else:
+            self.byte_count = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if instructions != None:
+            self.instructions = instructions
+        else:
+            self.instructions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 0
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!L", self.duration_sec))
+        packed.append(struct.pack("!L", self.duration_nsec))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append('\x00' * 6)
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.packet_count))
+        packed.append(struct.pack("!Q", self.byte_count))
+        packed.append(self.match.pack())
+        packed.append(loxi.generic_util.pack_list(self.instructions))
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_stats_entry()
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 2)
+        obj.table_id = reader.read("!B")[0]
+        reader.skip(1)
+        obj.duration_sec = reader.read("!L")[0]
+        obj.duration_nsec = reader.read("!L")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        reader.skip(6)
+        obj.cookie = reader.read("!Q")[0]
+        obj.packet_count = reader.read("!Q")[0]
+        obj.byte_count = reader.read("!Q")[0]
+        obj.match = ofp.match.unpack(reader)
+        obj.instructions = loxi.generic_util.unpack_list(reader, ofp.instruction.instruction.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.table_id != other.table_id: return False
+        if self.duration_sec != other.duration_sec: return False
+        if self.duration_nsec != other.duration_nsec: return False
+        if self.priority != other.priority: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.cookie != other.cookie: return False
+        if self.packet_count != other.packet_count: return False
+        if self.byte_count != other.byte_count: return False
+        if self.match != other.match: return False
+        if self.instructions != other.instructions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("duration_sec = ");
+                q.text("%#x" % self.duration_sec)
+                q.text(","); q.breakable()
+                q.text("duration_nsec = ");
+                q.text("%#x" % self.duration_nsec)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("packet_count = ");
+                q.text("%#x" % self.packet_count)
+                q.text(","); q.breakable()
+                q.text("byte_count = ");
+                q.text("%#x" % self.byte_count)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("instructions = ");
+                q.pp(self.instructions)
+            q.breakable()
+        q.text('}')
+
+
+class group_desc_stats_entry(loxi.OFObject):
+
+    def __init__(self, group_type=None, group_id=None, buckets=None):
+        if group_type != None:
+            self.group_type = group_type
+        else:
+            self.group_type = 0
+        if group_id != None:
+            self.group_id = group_id
+        else:
+            self.group_id = 0
+        if buckets != None:
+            self.buckets = buckets
+        else:
+            self.buckets = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 0
+        packed.append(struct.pack("!B", self.group_type))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!L", self.group_id))
+        packed.append(loxi.generic_util.pack_list(self.buckets))
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_desc_stats_entry()
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 2)
+        obj.group_type = reader.read("!B")[0]
+        reader.skip(1)
+        obj.group_id = reader.read("!L")[0]
+        obj.buckets = loxi.generic_util.unpack_list(reader, ofp.common.bucket.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.group_type != other.group_type: return False
+        if self.group_id != other.group_id: return False
+        if self.buckets != other.buckets: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_desc_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("group_type = ");
+                q.text("%#x" % self.group_type)
+                q.text(","); q.breakable()
+                q.text("group_id = ");
+                q.text("%#x" % self.group_id)
+                q.text(","); q.breakable()
+                q.text("buckets = ");
+                q.pp(self.buckets)
+            q.breakable()
+        q.text('}')
+
+
+class group_stats_entry(loxi.OFObject):
+
+    def __init__(self, group_id=None, ref_count=None, packet_count=None, byte_count=None, bucket_stats=None):
+        if group_id != None:
+            self.group_id = group_id
+        else:
+            self.group_id = 0
+        if ref_count != None:
+            self.ref_count = ref_count
+        else:
+            self.ref_count = 0
+        if packet_count != None:
+            self.packet_count = packet_count
+        else:
+            self.packet_count = 0
+        if byte_count != None:
+            self.byte_count = byte_count
+        else:
+            self.byte_count = 0
+        if bucket_stats != None:
+            self.bucket_stats = bucket_stats
+        else:
+            self.bucket_stats = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 0
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!L", self.group_id))
+        packed.append(struct.pack("!L", self.ref_count))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!Q", self.packet_count))
+        packed.append(struct.pack("!Q", self.byte_count))
+        packed.append(loxi.generic_util.pack_list(self.bucket_stats))
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_stats_entry()
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 2)
+        reader.skip(2)
+        obj.group_id = reader.read("!L")[0]
+        obj.ref_count = reader.read("!L")[0]
+        reader.skip(4)
+        obj.packet_count = reader.read("!Q")[0]
+        obj.byte_count = reader.read("!Q")[0]
+        obj.bucket_stats = loxi.generic_util.unpack_list(reader, ofp.common.bucket_counter.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.group_id != other.group_id: return False
+        if self.ref_count != other.ref_count: return False
+        if self.packet_count != other.packet_count: return False
+        if self.byte_count != other.byte_count: return False
+        if self.bucket_stats != other.bucket_stats: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("group_id = ");
+                q.text("%#x" % self.group_id)
+                q.text(","); q.breakable()
+                q.text("ref_count = ");
+                q.text("%#x" % self.ref_count)
+                q.text(","); q.breakable()
+                q.text("packet_count = ");
+                q.text("%#x" % self.packet_count)
+                q.text(","); q.breakable()
+                q.text("byte_count = ");
+                q.text("%#x" % self.byte_count)
+                q.text(","); q.breakable()
+                q.text("bucket_stats = ");
+                q.pp(self.bucket_stats)
+            q.breakable()
+        q.text('}')
+
+
+class match_v3(loxi.OFObject):
+    type = 1
+
+    def __init__(self, oxm_list=None):
+        if oxm_list != None:
+            self.oxm_list = oxm_list
+        else:
+            self.oxm_list = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(loxi.generic_util.pack_list(self.oxm_list))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        packed.append(loxi.generic_util.pad_to(8, length))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = match_v3()
+        _type = reader.read("!H")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.oxm_list = loxi.generic_util.unpack_list(reader, ofp.oxm.oxm.unpack)
+        orig_reader.skip_align()
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.oxm_list != other.oxm_list: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("match_v3 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("oxm_list = ");
+                q.pp(self.oxm_list)
+            q.breakable()
+        q.text('}')
+
+
+class packet_queue(loxi.OFObject):
+
+    def __init__(self, queue_id=None, port=None, properties=None):
+        if queue_id != None:
+            self.queue_id = queue_id
+        else:
+            self.queue_id = 0
+        if port != None:
+            self.port = port
+        else:
+            self.port = 0
+        if properties != None:
+            self.properties = properties
+        else:
+            self.properties = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.queue_id))
+        packed.append(util.pack_port_no(self.port))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 2
+        packed.append('\x00' * 6)
+        packed.append(loxi.generic_util.pack_list(self.properties))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = packet_queue()
+        obj.queue_id = reader.read("!L")[0]
+        obj.port = util.unpack_port_no(reader)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 10)
+        reader.skip(6)
+        obj.properties = loxi.generic_util.unpack_list(reader, ofp.common.queue_prop.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.queue_id != other.queue_id: return False
+        if self.port != other.port: return False
+        if self.properties != other.properties: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("packet_queue {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("queue_id = ");
+                q.text("%#x" % self.queue_id)
+                q.text(","); q.breakable()
+                q.text("port = ");
+                q.text(util.pretty_port(self.port))
+                q.text(","); q.breakable()
+                q.text("properties = ");
+                q.pp(self.properties)
+            q.breakable()
+        q.text('}')
+
+
+class port_desc(loxi.OFObject):
+
+    def __init__(self, port_no=None, hw_addr=None, name=None, config=None, state=None, curr=None, advertised=None, supported=None, peer=None, curr_speed=None, max_speed=None):
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if hw_addr != None:
+            self.hw_addr = hw_addr
+        else:
+            self.hw_addr = [0,0,0,0,0,0]
+        if name != None:
+            self.name = name
+        else:
+            self.name = ""
+        if config != None:
+            self.config = config
+        else:
+            self.config = 0
+        if state != None:
+            self.state = state
+        else:
+            self.state = 0
+        if curr != None:
+            self.curr = curr
+        else:
+            self.curr = 0
+        if advertised != None:
+            self.advertised = advertised
+        else:
+            self.advertised = 0
+        if supported != None:
+            self.supported = supported
+        else:
+            self.supported = 0
+        if peer != None:
+            self.peer = peer
+        else:
+            self.peer = 0
+        if curr_speed != None:
+            self.curr_speed = curr_speed
+        else:
+            self.curr_speed = 0
+        if max_speed != None:
+            self.max_speed = max_speed
+        else:
+            self.max_speed = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!6B", *self.hw_addr))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!16s", self.name))
+        packed.append(struct.pack("!L", self.config))
+        packed.append(struct.pack("!L", self.state))
+        packed.append(struct.pack("!L", self.curr))
+        packed.append(struct.pack("!L", self.advertised))
+        packed.append(struct.pack("!L", self.supported))
+        packed.append(struct.pack("!L", self.peer))
+        packed.append(struct.pack("!L", self.curr_speed))
+        packed.append(struct.pack("!L", self.max_speed))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_desc()
+        obj.port_no = util.unpack_port_no(reader)
+        reader.skip(4)
+        obj.hw_addr = list(reader.read('!6B'))
+        reader.skip(2)
+        obj.name = reader.read("!16s")[0].rstrip("\x00")
+        obj.config = reader.read("!L")[0]
+        obj.state = reader.read("!L")[0]
+        obj.curr = reader.read("!L")[0]
+        obj.advertised = reader.read("!L")[0]
+        obj.supported = reader.read("!L")[0]
+        obj.peer = reader.read("!L")[0]
+        obj.curr_speed = reader.read("!L")[0]
+        obj.max_speed = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.port_no != other.port_no: return False
+        if self.hw_addr != other.hw_addr: return False
+        if self.name != other.name: return False
+        if self.config != other.config: return False
+        if self.state != other.state: return False
+        if self.curr != other.curr: return False
+        if self.advertised != other.advertised: return False
+        if self.supported != other.supported: return False
+        if self.peer != other.peer: return False
+        if self.curr_speed != other.curr_speed: return False
+        if self.max_speed != other.max_speed: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_desc {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("hw_addr = ");
+                q.text(util.pretty_mac(self.hw_addr))
+                q.text(","); q.breakable()
+                q.text("name = ");
+                q.pp(self.name)
+                q.text(","); q.breakable()
+                q.text("config = ");
+                q.text("%#x" % self.config)
+                q.text(","); q.breakable()
+                q.text("state = ");
+                q.text("%#x" % self.state)
+                q.text(","); q.breakable()
+                q.text("curr = ");
+                q.text("%#x" % self.curr)
+                q.text(","); q.breakable()
+                q.text("advertised = ");
+                q.text("%#x" % self.advertised)
+                q.text(","); q.breakable()
+                q.text("supported = ");
+                q.text("%#x" % self.supported)
+                q.text(","); q.breakable()
+                q.text("peer = ");
+                q.text("%#x" % self.peer)
+                q.text(","); q.breakable()
+                q.text("curr_speed = ");
+                q.text("%#x" % self.curr_speed)
+                q.text(","); q.breakable()
+                q.text("max_speed = ");
+                q.text("%#x" % self.max_speed)
+            q.breakable()
+        q.text('}')
+
+
+class port_stats_entry(loxi.OFObject):
+
+    def __init__(self, port_no=None, rx_packets=None, tx_packets=None, rx_bytes=None, tx_bytes=None, rx_dropped=None, tx_dropped=None, rx_errors=None, tx_errors=None, rx_frame_err=None, rx_over_err=None, rx_crc_err=None, collisions=None):
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if rx_packets != None:
+            self.rx_packets = rx_packets
+        else:
+            self.rx_packets = 0
+        if tx_packets != None:
+            self.tx_packets = tx_packets
+        else:
+            self.tx_packets = 0
+        if rx_bytes != None:
+            self.rx_bytes = rx_bytes
+        else:
+            self.rx_bytes = 0
+        if tx_bytes != None:
+            self.tx_bytes = tx_bytes
+        else:
+            self.tx_bytes = 0
+        if rx_dropped != None:
+            self.rx_dropped = rx_dropped
+        else:
+            self.rx_dropped = 0
+        if tx_dropped != None:
+            self.tx_dropped = tx_dropped
+        else:
+            self.tx_dropped = 0
+        if rx_errors != None:
+            self.rx_errors = rx_errors
+        else:
+            self.rx_errors = 0
+        if tx_errors != None:
+            self.tx_errors = tx_errors
+        else:
+            self.tx_errors = 0
+        if rx_frame_err != None:
+            self.rx_frame_err = rx_frame_err
+        else:
+            self.rx_frame_err = 0
+        if rx_over_err != None:
+            self.rx_over_err = rx_over_err
+        else:
+            self.rx_over_err = 0
+        if rx_crc_err != None:
+            self.rx_crc_err = rx_crc_err
+        else:
+            self.rx_crc_err = 0
+        if collisions != None:
+            self.collisions = collisions
+        else:
+            self.collisions = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!Q", self.rx_packets))
+        packed.append(struct.pack("!Q", self.tx_packets))
+        packed.append(struct.pack("!Q", self.rx_bytes))
+        packed.append(struct.pack("!Q", self.tx_bytes))
+        packed.append(struct.pack("!Q", self.rx_dropped))
+        packed.append(struct.pack("!Q", self.tx_dropped))
+        packed.append(struct.pack("!Q", self.rx_errors))
+        packed.append(struct.pack("!Q", self.tx_errors))
+        packed.append(struct.pack("!Q", self.rx_frame_err))
+        packed.append(struct.pack("!Q", self.rx_over_err))
+        packed.append(struct.pack("!Q", self.rx_crc_err))
+        packed.append(struct.pack("!Q", self.collisions))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_stats_entry()
+        obj.port_no = util.unpack_port_no(reader)
+        reader.skip(4)
+        obj.rx_packets = reader.read("!Q")[0]
+        obj.tx_packets = reader.read("!Q")[0]
+        obj.rx_bytes = reader.read("!Q")[0]
+        obj.tx_bytes = reader.read("!Q")[0]
+        obj.rx_dropped = reader.read("!Q")[0]
+        obj.tx_dropped = reader.read("!Q")[0]
+        obj.rx_errors = reader.read("!Q")[0]
+        obj.tx_errors = reader.read("!Q")[0]
+        obj.rx_frame_err = reader.read("!Q")[0]
+        obj.rx_over_err = reader.read("!Q")[0]
+        obj.rx_crc_err = reader.read("!Q")[0]
+        obj.collisions = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.port_no != other.port_no: return False
+        if self.rx_packets != other.rx_packets: return False
+        if self.tx_packets != other.tx_packets: return False
+        if self.rx_bytes != other.rx_bytes: return False
+        if self.tx_bytes != other.tx_bytes: return False
+        if self.rx_dropped != other.rx_dropped: return False
+        if self.tx_dropped != other.tx_dropped: return False
+        if self.rx_errors != other.rx_errors: return False
+        if self.tx_errors != other.tx_errors: return False
+        if self.rx_frame_err != other.rx_frame_err: return False
+        if self.rx_over_err != other.rx_over_err: return False
+        if self.rx_crc_err != other.rx_crc_err: return False
+        if self.collisions != other.collisions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("rx_packets = ");
+                q.text("%#x" % self.rx_packets)
+                q.text(","); q.breakable()
+                q.text("tx_packets = ");
+                q.text("%#x" % self.tx_packets)
+                q.text(","); q.breakable()
+                q.text("rx_bytes = ");
+                q.text("%#x" % self.rx_bytes)
+                q.text(","); q.breakable()
+                q.text("tx_bytes = ");
+                q.text("%#x" % self.tx_bytes)
+                q.text(","); q.breakable()
+                q.text("rx_dropped = ");
+                q.text("%#x" % self.rx_dropped)
+                q.text(","); q.breakable()
+                q.text("tx_dropped = ");
+                q.text("%#x" % self.tx_dropped)
+                q.text(","); q.breakable()
+                q.text("rx_errors = ");
+                q.text("%#x" % self.rx_errors)
+                q.text(","); q.breakable()
+                q.text("tx_errors = ");
+                q.text("%#x" % self.tx_errors)
+                q.text(","); q.breakable()
+                q.text("rx_frame_err = ");
+                q.text("%#x" % self.rx_frame_err)
+                q.text(","); q.breakable()
+                q.text("rx_over_err = ");
+                q.text("%#x" % self.rx_over_err)
+                q.text(","); q.breakable()
+                q.text("rx_crc_err = ");
+                q.text("%#x" % self.rx_crc_err)
+                q.text(","); q.breakable()
+                q.text("collisions = ");
+                q.text("%#x" % self.collisions)
+            q.breakable()
+        q.text('}')
+
+
+class queue_prop(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = queue_prop.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = queue_prop()
+        obj.type = reader.read("!H")[0]
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_prop {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class queue_prop_experimenter(queue_prop):
+    subtypes = {}
+
+    type = 65535
+
+    def __init__(self, experimenter=None, data=None):
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append('\x00' * 4)
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 8)
+        subclass = queue_prop_experimenter.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = queue_prop_experimenter()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        obj.experimenter = reader.read("!L")[0]
+        reader.skip(4)
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.experimenter != other.experimenter: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_prop_experimenter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+queue_prop.subtypes[65535] = queue_prop_experimenter
+
+class queue_prop_max_rate(queue_prop):
+    type = 2
+
+    def __init__(self, rate=None):
+        if rate != None:
+            self.rate = rate
+        else:
+            self.rate = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!H", self.rate))
+        packed.append('\x00' * 6)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_prop_max_rate()
+        _type = reader.read("!H")[0]
+        assert(_type == 2)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        obj.rate = reader.read("!H")[0]
+        reader.skip(6)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.rate != other.rate: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_prop_max_rate {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("rate = ");
+                q.text("%#x" % self.rate)
+            q.breakable()
+        q.text('}')
+
+queue_prop.subtypes[2] = queue_prop_max_rate
+
+class queue_prop_min_rate(queue_prop):
+    type = 1
+
+    def __init__(self, rate=None):
+        if rate != None:
+            self.rate = rate
+        else:
+            self.rate = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!H", self.rate))
+        packed.append('\x00' * 6)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_prop_min_rate()
+        _type = reader.read("!H")[0]
+        assert(_type == 1)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        obj.rate = reader.read("!H")[0]
+        reader.skip(6)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.rate != other.rate: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_prop_min_rate {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("rate = ");
+                q.text("%#x" % self.rate)
+            q.breakable()
+        q.text('}')
+
+queue_prop.subtypes[1] = queue_prop_min_rate
+
+class queue_stats_entry(loxi.OFObject):
+
+    def __init__(self, port_no=None, queue_id=None, tx_bytes=None, tx_packets=None, tx_errors=None):
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if queue_id != None:
+            self.queue_id = queue_id
+        else:
+            self.queue_id = 0
+        if tx_bytes != None:
+            self.tx_bytes = tx_bytes
+        else:
+            self.tx_bytes = 0
+        if tx_packets != None:
+            self.tx_packets = tx_packets
+        else:
+            self.tx_packets = 0
+        if tx_errors != None:
+            self.tx_errors = tx_errors
+        else:
+            self.tx_errors = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!L", self.queue_id))
+        packed.append(struct.pack("!Q", self.tx_bytes))
+        packed.append(struct.pack("!Q", self.tx_packets))
+        packed.append(struct.pack("!Q", self.tx_errors))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_stats_entry()
+        obj.port_no = util.unpack_port_no(reader)
+        obj.queue_id = reader.read("!L")[0]
+        obj.tx_bytes = reader.read("!Q")[0]
+        obj.tx_packets = reader.read("!Q")[0]
+        obj.tx_errors = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.port_no != other.port_no: return False
+        if self.queue_id != other.queue_id: return False
+        if self.tx_bytes != other.tx_bytes: return False
+        if self.tx_packets != other.tx_packets: return False
+        if self.tx_errors != other.tx_errors: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("queue_id = ");
+                q.text("%#x" % self.queue_id)
+                q.text(","); q.breakable()
+                q.text("tx_bytes = ");
+                q.text("%#x" % self.tx_bytes)
+                q.text(","); q.breakable()
+                q.text("tx_packets = ");
+                q.text("%#x" % self.tx_packets)
+                q.text(","); q.breakable()
+                q.text("tx_errors = ");
+                q.text("%#x" % self.tx_errors)
+            q.breakable()
+        q.text('}')
+
+
+class table_stats_entry(loxi.OFObject):
+
+    def __init__(self, table_id=None, name=None, match=None, wildcards=None, write_actions=None, apply_actions=None, write_setfields=None, apply_setfields=None, metadata_match=None, metadata_write=None, instructions=None, config=None, max_entries=None, active_count=None, lookup_count=None, matched_count=None):
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if name != None:
+            self.name = name
+        else:
+            self.name = ""
+        if match != None:
+            self.match = match
+        else:
+            self.match = util.init_match_bmap()
+        if wildcards != None:
+            self.wildcards = wildcards
+        else:
+            self.wildcards = util.init_wc_bmap()
+        if write_actions != None:
+            self.write_actions = write_actions
+        else:
+            self.write_actions = 0
+        if apply_actions != None:
+            self.apply_actions = apply_actions
+        else:
+            self.apply_actions = 0
+        if write_setfields != None:
+            self.write_setfields = write_setfields
+        else:
+            self.write_setfields = 0
+        if apply_setfields != None:
+            self.apply_setfields = apply_setfields
+        else:
+            self.apply_setfields = 0
+        if metadata_match != None:
+            self.metadata_match = metadata_match
+        else:
+            self.metadata_match = 0
+        if metadata_write != None:
+            self.metadata_write = metadata_write
+        else:
+            self.metadata_write = 0
+        if instructions != None:
+            self.instructions = instructions
+        else:
+            self.instructions = 0
+        if config != None:
+            self.config = config
+        else:
+            self.config = 0
+        if max_entries != None:
+            self.max_entries = max_entries
+        else:
+            self.max_entries = 0
+        if active_count != None:
+            self.active_count = active_count
+        else:
+            self.active_count = 0
+        if lookup_count != None:
+            self.lookup_count = lookup_count
+        else:
+            self.lookup_count = 0
+        if matched_count != None:
+            self.matched_count = matched_count
+        else:
+            self.matched_count = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append('\x00' * 7)
+        packed.append(struct.pack("!32s", self.name))
+        packed.append(util.pack_match_bmap(self.match))
+        packed.append(util.pack_wc_bmap(self.wildcards))
+        packed.append(struct.pack("!L", self.write_actions))
+        packed.append(struct.pack("!L", self.apply_actions))
+        packed.append(struct.pack("!Q", self.write_setfields))
+        packed.append(struct.pack("!Q", self.apply_setfields))
+        packed.append(struct.pack("!Q", self.metadata_match))
+        packed.append(struct.pack("!Q", self.metadata_write))
+        packed.append(struct.pack("!L", self.instructions))
+        packed.append(struct.pack("!L", self.config))
+        packed.append(struct.pack("!L", self.max_entries))
+        packed.append(struct.pack("!L", self.active_count))
+        packed.append(struct.pack("!Q", self.lookup_count))
+        packed.append(struct.pack("!Q", self.matched_count))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_stats_entry()
+        obj.table_id = reader.read("!B")[0]
+        reader.skip(7)
+        obj.name = reader.read("!32s")[0].rstrip("\x00")
+        obj.match = util.unpack_match_bmap(reader)
+        obj.wildcards = util.unpack_wc_bmap(reader)
+        obj.write_actions = reader.read("!L")[0]
+        obj.apply_actions = reader.read("!L")[0]
+        obj.write_setfields = reader.read("!Q")[0]
+        obj.apply_setfields = reader.read("!Q")[0]
+        obj.metadata_match = reader.read("!Q")[0]
+        obj.metadata_write = reader.read("!Q")[0]
+        obj.instructions = reader.read("!L")[0]
+        obj.config = reader.read("!L")[0]
+        obj.max_entries = reader.read("!L")[0]
+        obj.active_count = reader.read("!L")[0]
+        obj.lookup_count = reader.read("!Q")[0]
+        obj.matched_count = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.table_id != other.table_id: return False
+        if self.name != other.name: return False
+        if self.match != other.match: return False
+        if self.wildcards != other.wildcards: return False
+        if self.write_actions != other.write_actions: return False
+        if self.apply_actions != other.apply_actions: return False
+        if self.write_setfields != other.write_setfields: return False
+        if self.apply_setfields != other.apply_setfields: return False
+        if self.metadata_match != other.metadata_match: return False
+        if self.metadata_write != other.metadata_write: return False
+        if self.instructions != other.instructions: return False
+        if self.config != other.config: return False
+        if self.max_entries != other.max_entries: return False
+        if self.active_count != other.active_count: return False
+        if self.lookup_count != other.lookup_count: return False
+        if self.matched_count != other.matched_count: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("name = ");
+                q.pp(self.name)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("wildcards = ");
+                q.pp(self.wildcards)
+                q.text(","); q.breakable()
+                q.text("write_actions = ");
+                q.text("%#x" % self.write_actions)
+                q.text(","); q.breakable()
+                q.text("apply_actions = ");
+                q.text("%#x" % self.apply_actions)
+                q.text(","); q.breakable()
+                q.text("write_setfields = ");
+                q.text("%#x" % self.write_setfields)
+                q.text(","); q.breakable()
+                q.text("apply_setfields = ");
+                q.text("%#x" % self.apply_setfields)
+                q.text(","); q.breakable()
+                q.text("metadata_match = ");
+                q.text("%#x" % self.metadata_match)
+                q.text(","); q.breakable()
+                q.text("metadata_write = ");
+                q.text("%#x" % self.metadata_write)
+                q.text(","); q.breakable()
+                q.text("instructions = ");
+                q.text("%#x" % self.instructions)
+                q.text(","); q.breakable()
+                q.text("config = ");
+                q.text("%#x" % self.config)
+                q.text(","); q.breakable()
+                q.text("max_entries = ");
+                q.text("%#x" % self.max_entries)
+                q.text(","); q.breakable()
+                q.text("active_count = ");
+                q.text("%#x" % self.active_count)
+                q.text(","); q.breakable()
+                q.text("lookup_count = ");
+                q.text("%#x" % self.lookup_count)
+                q.text(","); q.breakable()
+                q.text("matched_count = ");
+                q.text("%#x" % self.matched_count)
+            q.breakable()
+        q.text('}')
+
+
+
+match = match_v3
diff --git a/Fabric/Utilities/src/python/loxi/of12/const.py b/Fabric/Utilities/src/python/loxi/of12/const.py
new file mode 100644
index 0000000..70a63f8
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of12/const.py
@@ -0,0 +1,840 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template const.py
+# Do not modify
+
+OFP_VERSION = 3
+
+# Identifiers from group macro_definitions
+OFP_MAX_TABLE_NAME_LEN = 32
+OFP_MAX_PORT_NAME_LEN = 16
+OFP_TCP_PORT = 6653
+OFP_SSL_PORT = 6653
+OFP_ETH_ALEN = 6
+OFP_DEFAULT_MISS_SEND_LEN = 128
+OFP_VLAN_NONE = 0
+OFP_FLOW_PERMANENT = 0
+OFP_DEFAULT_PRIORITY = 32768
+OFP_NO_BUFFER = 4294967295
+DESC_STR_LEN = 256
+SERIAL_NUM_LEN = 32
+OFPQ_ALL = 4294967295
+OFPQ_MIN_RATE_UNCFG = 65535
+OFPQ_MAX_RATE_UNCFG = 65535
+
+# Identifiers from group of_bsn_pdu_slot_num
+BSN_PDU_SLOT_NUM_ANY = 255
+
+of_bsn_pdu_slot_num_map = {
+    255: 'BSN_PDU_SLOT_NUM_ANY',
+}
+
+# Identifiers from group ofp_action_type
+OFPAT_OUTPUT = 0
+OFPAT_COPY_TTL_OUT = 11
+OFPAT_COPY_TTL_IN = 12
+OFPAT_SET_MPLS_TTL = 15
+OFPAT_DEC_MPLS_TTL = 16
+OFPAT_PUSH_VLAN = 17
+OFPAT_POP_VLAN = 18
+OFPAT_PUSH_MPLS = 19
+OFPAT_POP_MPLS = 20
+OFPAT_SET_QUEUE = 21
+OFPAT_GROUP = 22
+OFPAT_SET_NW_TTL = 23
+OFPAT_DEC_NW_TTL = 24
+OFPAT_SET_FIELD = 25
+OFPAT_EXPERIMENTER = 65535
+
+ofp_action_type_map = {
+    0: 'OFPAT_OUTPUT',
+    11: 'OFPAT_COPY_TTL_OUT',
+    12: 'OFPAT_COPY_TTL_IN',
+    15: 'OFPAT_SET_MPLS_TTL',
+    16: 'OFPAT_DEC_MPLS_TTL',
+    17: 'OFPAT_PUSH_VLAN',
+    18: 'OFPAT_POP_VLAN',
+    19: 'OFPAT_PUSH_MPLS',
+    20: 'OFPAT_POP_MPLS',
+    21: 'OFPAT_SET_QUEUE',
+    22: 'OFPAT_GROUP',
+    23: 'OFPAT_SET_NW_TTL',
+    24: 'OFPAT_DEC_NW_TTL',
+    25: 'OFPAT_SET_FIELD',
+    65535: 'OFPAT_EXPERIMENTER',
+}
+
+# Identifiers from group ofp_bad_action_code
+OFPBAC_BAD_TYPE = 0
+OFPBAC_BAD_LEN = 1
+OFPBAC_BAD_EXPERIMENTER = 2
+OFPBAC_BAD_EXPERIMENTER_TYPE = 3
+OFPBAC_BAD_OUT_PORT = 4
+OFPBAC_BAD_ARGUMENT = 5
+OFPBAC_EPERM = 6
+OFPBAC_TOO_MANY = 7
+OFPBAC_BAD_QUEUE = 8
+OFPBAC_BAD_OUT_GROUP = 9
+OFPBAC_MATCH_INCONSISTENT = 10
+OFPBAC_UNSUPPORTED_ORDER = 11
+OFPBAC_BAD_TAG = 12
+OFPBAC_BAD_SET_TYPE = 13
+OFPBAC_BAD_SET_LEN = 14
+OFPBAC_BAD_SET_ARGUMENT = 15
+
+ofp_bad_action_code_map = {
+    0: 'OFPBAC_BAD_TYPE',
+    1: 'OFPBAC_BAD_LEN',
+    2: 'OFPBAC_BAD_EXPERIMENTER',
+    3: 'OFPBAC_BAD_EXPERIMENTER_TYPE',
+    4: 'OFPBAC_BAD_OUT_PORT',
+    5: 'OFPBAC_BAD_ARGUMENT',
+    6: 'OFPBAC_EPERM',
+    7: 'OFPBAC_TOO_MANY',
+    8: 'OFPBAC_BAD_QUEUE',
+    9: 'OFPBAC_BAD_OUT_GROUP',
+    10: 'OFPBAC_MATCH_INCONSISTENT',
+    11: 'OFPBAC_UNSUPPORTED_ORDER',
+    12: 'OFPBAC_BAD_TAG',
+    13: 'OFPBAC_BAD_SET_TYPE',
+    14: 'OFPBAC_BAD_SET_LEN',
+    15: 'OFPBAC_BAD_SET_ARGUMENT',
+}
+
+# Identifiers from group ofp_bad_instruction_code
+OFPBIC_UNKNOWN_INST = 0
+OFPBIC_UNSUP_INST = 1
+OFPBIC_BAD_TABLE_ID = 2
+OFPBIC_UNSUP_METADATA = 3
+OFPBIC_UNSUP_METADATA_MASK = 4
+OFPBIC_BAD_EXPERIMENTER = 5
+OFPBIC_BAD_EXPERIMENTER_TYPE = 6
+OFPBIC_BAD_LEN = 7
+OFPBIC_EPERM = 8
+
+ofp_bad_instruction_code_map = {
+    0: 'OFPBIC_UNKNOWN_INST',
+    1: 'OFPBIC_UNSUP_INST',
+    2: 'OFPBIC_BAD_TABLE_ID',
+    3: 'OFPBIC_UNSUP_METADATA',
+    4: 'OFPBIC_UNSUP_METADATA_MASK',
+    5: 'OFPBIC_BAD_EXPERIMENTER',
+    6: 'OFPBIC_BAD_EXPERIMENTER_TYPE',
+    7: 'OFPBIC_BAD_LEN',
+    8: 'OFPBIC_EPERM',
+}
+
+# Identifiers from group ofp_bad_match_code
+OFPBMC_BAD_TYPE = 0
+OFPBMC_BAD_LEN = 1
+OFPBMC_BAD_TAG = 2
+OFPBMC_BAD_DL_ADDR_MASK = 3
+OFPBMC_BAD_NW_ADDR_MASK = 4
+OFPBMC_BAD_WILDCARDS = 5
+OFPBMC_BAD_FIELD = 6
+OFPBMC_BAD_VALUE = 7
+OFPBMC_BAD_MASK = 8
+OFPBMC_BAD_PREREQ = 9
+OFPBMC_DUP_FIELD = 10
+OFPBMC_EPERM = 11
+
+ofp_bad_match_code_map = {
+    0: 'OFPBMC_BAD_TYPE',
+    1: 'OFPBMC_BAD_LEN',
+    2: 'OFPBMC_BAD_TAG',
+    3: 'OFPBMC_BAD_DL_ADDR_MASK',
+    4: 'OFPBMC_BAD_NW_ADDR_MASK',
+    5: 'OFPBMC_BAD_WILDCARDS',
+    6: 'OFPBMC_BAD_FIELD',
+    7: 'OFPBMC_BAD_VALUE',
+    8: 'OFPBMC_BAD_MASK',
+    9: 'OFPBMC_BAD_PREREQ',
+    10: 'OFPBMC_DUP_FIELD',
+    11: 'OFPBMC_EPERM',
+}
+
+# Identifiers from group ofp_bad_request_code
+OFPBRC_BAD_VERSION = 0
+OFPBRC_BAD_TYPE = 1
+OFPBRC_BAD_STAT = 2
+OFPBRC_BAD_EXPERIMENTER = 3
+OFPBRC_BAD_EXPERIMENTER_TYPE = 4
+OFPBRC_EPERM = 5
+OFPBRC_BAD_LEN = 6
+OFPBRC_BUFFER_EMPTY = 7
+OFPBRC_BUFFER_UNKNOWN = 8
+OFPBRC_BAD_TABLE_ID = 9
+OFPBRC_IS_SLAVE = 10
+OFPBRC_BAD_PORT = 11
+OFPBRC_BAD_PACKET = 12
+
+ofp_bad_request_code_map = {
+    0: 'OFPBRC_BAD_VERSION',
+    1: 'OFPBRC_BAD_TYPE',
+    2: 'OFPBRC_BAD_STAT',
+    3: 'OFPBRC_BAD_EXPERIMENTER',
+    4: 'OFPBRC_BAD_EXPERIMENTER_TYPE',
+    5: 'OFPBRC_EPERM',
+    6: 'OFPBRC_BAD_LEN',
+    7: 'OFPBRC_BUFFER_EMPTY',
+    8: 'OFPBRC_BUFFER_UNKNOWN',
+    9: 'OFPBRC_BAD_TABLE_ID',
+    10: 'OFPBRC_IS_SLAVE',
+    11: 'OFPBRC_BAD_PORT',
+    12: 'OFPBRC_BAD_PACKET',
+}
+
+# Identifiers from group ofp_bsn_tcp_flag
+OFP_BSN_TCP_FLAG_FIN = 1
+OFP_BSN_TCP_FLAG_SYN = 2
+OFP_BSN_TCP_FLAG_RST = 4
+OFP_BSN_TCP_FLAG_PSH = 8
+OFP_BSN_TCP_FLAG_ACK = 16
+OFP_BSN_TCP_FLAG_URG = 32
+OFP_BSN_TCP_FLAG_ECE = 64
+OFP_BSN_TCP_FLAG_CWR = 128
+OFP_BSN_TCP_FLAG_NS = 256
+
+ofp_bsn_tcp_flag_map = {
+    1: 'OFP_BSN_TCP_FLAG_FIN',
+    2: 'OFP_BSN_TCP_FLAG_SYN',
+    4: 'OFP_BSN_TCP_FLAG_RST',
+    8: 'OFP_BSN_TCP_FLAG_PSH',
+    16: 'OFP_BSN_TCP_FLAG_ACK',
+    32: 'OFP_BSN_TCP_FLAG_URG',
+    64: 'OFP_BSN_TCP_FLAG_ECE',
+    128: 'OFP_BSN_TCP_FLAG_CWR',
+    256: 'OFP_BSN_TCP_FLAG_NS',
+}
+
+# Identifiers from group ofp_bsn_vport_l2gre_flags
+OF_BSN_VPORT_L2GRE_LOCAL_MAC_IS_VALID = 1
+OF_BSN_VPORT_L2GRE_DSCP_ASSIGN = 2
+OF_BSN_VPORT_L2GRE_DSCP_COPY = 4
+OF_BSN_VPORT_L2GRE_LOOPBACK_IS_VALID = 8
+OF_BSN_VPORT_L2GRE_RATE_LIMIT_IS_VALID = 16
+
+ofp_bsn_vport_l2gre_flags_map = {
+    1: 'OF_BSN_VPORT_L2GRE_LOCAL_MAC_IS_VALID',
+    2: 'OF_BSN_VPORT_L2GRE_DSCP_ASSIGN',
+    4: 'OF_BSN_VPORT_L2GRE_DSCP_COPY',
+    8: 'OF_BSN_VPORT_L2GRE_LOOPBACK_IS_VALID',
+    16: 'OF_BSN_VPORT_L2GRE_RATE_LIMIT_IS_VALID',
+}
+
+# Identifiers from group ofp_bsn_vport_q_in_q_untagged
+OF_BSN_VPORT_Q_IN_Q_UNTAGGED = 65535
+
+ofp_bsn_vport_q_in_q_untagged_map = {
+    65535: 'OF_BSN_VPORT_Q_IN_Q_UNTAGGED',
+}
+
+# Identifiers from group ofp_bsn_vport_status
+OF_BSN_VPORT_STATUS_OK = 0
+OF_BSN_VPORT_STATUS_FAILED = 1
+
+ofp_bsn_vport_status_map = {
+    0: 'OF_BSN_VPORT_STATUS_OK',
+    1: 'OF_BSN_VPORT_STATUS_FAILED',
+}
+
+# Identifiers from group ofp_capabilities
+OFPC_FLOW_STATS = 1
+OFPC_TABLE_STATS = 2
+OFPC_PORT_STATS = 4
+OFPC_GROUP_STATS = 8
+OFPC_IP_REASM = 32
+OFPC_QUEUE_STATS = 64
+OFPC_PORT_BLOCKED = 256
+
+ofp_capabilities_map = {
+    1: 'OFPC_FLOW_STATS',
+    2: 'OFPC_TABLE_STATS',
+    4: 'OFPC_PORT_STATS',
+    8: 'OFPC_GROUP_STATS',
+    32: 'OFPC_IP_REASM',
+    64: 'OFPC_QUEUE_STATS',
+    256: 'OFPC_PORT_BLOCKED',
+}
+
+# Identifiers from group ofp_config_flags
+OFPC_FRAG_NORMAL = 0
+OFPC_FRAG_DROP = 1
+OFPC_FRAG_REASM = 2
+OFPC_FRAG_MASK = 3
+OFPC_INVALID_TTL_TO_CONTROLLER = 4
+
+ofp_config_flags_map = {
+    0: 'OFPC_FRAG_NORMAL',
+    1: 'OFPC_FRAG_DROP',
+    2: 'OFPC_FRAG_REASM',
+    3: 'OFPC_FRAG_MASK',
+    4: 'OFPC_INVALID_TTL_TO_CONTROLLER',
+}
+
+# Identifiers from group ofp_controller_max_len
+OFPCML_MAX = 65509
+OFPCML_NO_BUFFER = 65535
+
+ofp_controller_max_len_map = {
+    65509: 'OFPCML_MAX',
+    65535: 'OFPCML_NO_BUFFER',
+}
+
+# Identifiers from group ofp_controller_role
+OFPCR_ROLE_NOCHANGE = 0
+OFPCR_ROLE_EQUAL = 1
+OFPCR_ROLE_MASTER = 2
+OFPCR_ROLE_SLAVE = 3
+
+ofp_controller_role_map = {
+    0: 'OFPCR_ROLE_NOCHANGE',
+    1: 'OFPCR_ROLE_EQUAL',
+    2: 'OFPCR_ROLE_MASTER',
+    3: 'OFPCR_ROLE_SLAVE',
+}
+
+# Identifiers from group ofp_error_type
+OFPET_HELLO_FAILED = 0
+OFPET_BAD_REQUEST = 1
+OFPET_BAD_ACTION = 2
+OFPET_BAD_INSTRUCTION = 3
+OFPET_BAD_MATCH = 4
+OFPET_FLOW_MOD_FAILED = 5
+OFPET_GROUP_MOD_FAILED = 6
+OFPET_PORT_MOD_FAILED = 7
+OFPET_TABLE_MOD_FAILED = 8
+OFPET_QUEUE_OP_FAILED = 9
+OFPET_SWITCH_CONFIG_FAILED = 10
+OFPET_ROLE_REQUEST_FAILED = 11
+OFPET_EXPERIMENTER = 65535
+
+ofp_error_type_map = {
+    0: 'OFPET_HELLO_FAILED',
+    1: 'OFPET_BAD_REQUEST',
+    2: 'OFPET_BAD_ACTION',
+    3: 'OFPET_BAD_INSTRUCTION',
+    4: 'OFPET_BAD_MATCH',
+    5: 'OFPET_FLOW_MOD_FAILED',
+    6: 'OFPET_GROUP_MOD_FAILED',
+    7: 'OFPET_PORT_MOD_FAILED',
+    8: 'OFPET_TABLE_MOD_FAILED',
+    9: 'OFPET_QUEUE_OP_FAILED',
+    10: 'OFPET_SWITCH_CONFIG_FAILED',
+    11: 'OFPET_ROLE_REQUEST_FAILED',
+    65535: 'OFPET_EXPERIMENTER',
+}
+
+# Identifiers from group ofp_flow_mod_command
+OFPFC_ADD = 0
+OFPFC_MODIFY = 1
+OFPFC_MODIFY_STRICT = 2
+OFPFC_DELETE = 3
+OFPFC_DELETE_STRICT = 4
+
+ofp_flow_mod_command_map = {
+    0: 'OFPFC_ADD',
+    1: 'OFPFC_MODIFY',
+    2: 'OFPFC_MODIFY_STRICT',
+    3: 'OFPFC_DELETE',
+    4: 'OFPFC_DELETE_STRICT',
+}
+
+# Identifiers from group ofp_flow_mod_failed_code
+OFPFMFC_UNKNOWN = 0
+OFPFMFC_TABLE_FULL = 1
+OFPFMFC_BAD_TABLE_ID = 2
+OFPFMFC_OVERLAP = 3
+OFPFMFC_EPERM = 4
+OFPFMFC_BAD_TIMEOUT = 5
+OFPFMFC_BAD_COMMAND = 6
+OFPFMFC_BAD_FLAGS = 7
+
+ofp_flow_mod_failed_code_map = {
+    0: 'OFPFMFC_UNKNOWN',
+    1: 'OFPFMFC_TABLE_FULL',
+    2: 'OFPFMFC_BAD_TABLE_ID',
+    3: 'OFPFMFC_OVERLAP',
+    4: 'OFPFMFC_EPERM',
+    5: 'OFPFMFC_BAD_TIMEOUT',
+    6: 'OFPFMFC_BAD_COMMAND',
+    7: 'OFPFMFC_BAD_FLAGS',
+}
+
+# Identifiers from group ofp_flow_mod_flags
+OFPFF_SEND_FLOW_REM = 1
+OFPFF_CHECK_OVERLAP = 2
+OFPFF_RESET_COUNTS = 4
+
+ofp_flow_mod_flags_map = {
+    1: 'OFPFF_SEND_FLOW_REM',
+    2: 'OFPFF_CHECK_OVERLAP',
+    4: 'OFPFF_RESET_COUNTS',
+}
+
+# Identifiers from group ofp_flow_removed_reason
+OFPRR_IDLE_TIMEOUT = 0
+OFPRR_HARD_TIMEOUT = 1
+OFPRR_DELETE = 2
+OFPRR_GROUP_DELETE = 3
+
+ofp_flow_removed_reason_map = {
+    0: 'OFPRR_IDLE_TIMEOUT',
+    1: 'OFPRR_HARD_TIMEOUT',
+    2: 'OFPRR_DELETE',
+    3: 'OFPRR_GROUP_DELETE',
+}
+
+# Identifiers from group ofp_group
+OFPG_MAX = 4294967040
+OFPG_ALL = 4294967292
+OFPG_ANY = 4294967295
+
+ofp_group_map = {
+    4294967040: 'OFPG_MAX',
+    4294967292: 'OFPG_ALL',
+    4294967295: 'OFPG_ANY',
+}
+
+# Identifiers from group ofp_group_capabilities
+OFPGFC_SELECT_WEIGHT = 1
+OFPGFC_SELECT_LIVENESS = 2
+OFPGFC_CHAINING = 4
+OFPGFC_CHAINING_CHECKS = 8
+
+ofp_group_capabilities_map = {
+    1: 'OFPGFC_SELECT_WEIGHT',
+    2: 'OFPGFC_SELECT_LIVENESS',
+    4: 'OFPGFC_CHAINING',
+    8: 'OFPGFC_CHAINING_CHECKS',
+}
+
+# Identifiers from group ofp_group_mod_command
+OFPGC_ADD = 0
+OFPGC_MODIFY = 1
+OFPGC_DELETE = 2
+
+ofp_group_mod_command_map = {
+    0: 'OFPGC_ADD',
+    1: 'OFPGC_MODIFY',
+    2: 'OFPGC_DELETE',
+}
+
+# Identifiers from group ofp_group_mod_failed_code
+OFPGMFC_GROUP_EXISTS = 0
+OFPGMFC_INVALID_GROUP = 1
+OFPGMFC_WEIGHT_UNSUPPORTED = 2
+OFPGMFC_OUT_OF_GROUPS = 3
+OFPGMFC_OUT_OF_BUCKETS = 4
+OFPGMFC_CHAINING_UNSUPPORTED = 5
+OFPGMFC_WATCH_UNSUPPORTED = 6
+OFPGMFC_LOOP = 7
+OFPGMFC_UNKNOWN_GROUP = 8
+OFPGMFC_CHAINED_GROUP = 9
+OFPGMFC_BAD_TYPE = 10
+OFPGMFC_BAD_COMMAND = 11
+OFPGMFC_BAD_BUCKET = 12
+OFPGMFC_BAD_WATCH = 13
+OFPGMFC_EPERM = 14
+
+ofp_group_mod_failed_code_map = {
+    0: 'OFPGMFC_GROUP_EXISTS',
+    1: 'OFPGMFC_INVALID_GROUP',
+    2: 'OFPGMFC_WEIGHT_UNSUPPORTED',
+    3: 'OFPGMFC_OUT_OF_GROUPS',
+    4: 'OFPGMFC_OUT_OF_BUCKETS',
+    5: 'OFPGMFC_CHAINING_UNSUPPORTED',
+    6: 'OFPGMFC_WATCH_UNSUPPORTED',
+    7: 'OFPGMFC_LOOP',
+    8: 'OFPGMFC_UNKNOWN_GROUP',
+    9: 'OFPGMFC_CHAINED_GROUP',
+    10: 'OFPGMFC_BAD_TYPE',
+    11: 'OFPGMFC_BAD_COMMAND',
+    12: 'OFPGMFC_BAD_BUCKET',
+    13: 'OFPGMFC_BAD_WATCH',
+    14: 'OFPGMFC_EPERM',
+}
+
+# Identifiers from group ofp_group_type
+OFPGT_ALL = 0
+OFPGT_SELECT = 1
+OFPGT_INDIRECT = 2
+OFPGT_FF = 3
+
+ofp_group_type_map = {
+    0: 'OFPGT_ALL',
+    1: 'OFPGT_SELECT',
+    2: 'OFPGT_INDIRECT',
+    3: 'OFPGT_FF',
+}
+
+# Identifiers from group ofp_hello_failed_code
+OFPHFC_INCOMPATIBLE = 0
+OFPHFC_EPERM = 1
+
+ofp_hello_failed_code_map = {
+    0: 'OFPHFC_INCOMPATIBLE',
+    1: 'OFPHFC_EPERM',
+}
+
+# Identifiers from group ofp_instruction_type
+OFPIT_GOTO_TABLE = 1
+OFPIT_WRITE_METADATA = 2
+OFPIT_WRITE_ACTIONS = 3
+OFPIT_APPLY_ACTIONS = 4
+OFPIT_CLEAR_ACTIONS = 5
+OFPIT_EXPERIMENTER = 65535
+
+ofp_instruction_type_map = {
+    1: 'OFPIT_GOTO_TABLE',
+    2: 'OFPIT_WRITE_METADATA',
+    3: 'OFPIT_WRITE_ACTIONS',
+    4: 'OFPIT_APPLY_ACTIONS',
+    5: 'OFPIT_CLEAR_ACTIONS',
+    65535: 'OFPIT_EXPERIMENTER',
+}
+
+# Identifiers from group ofp_match_type
+OFPMT_STANDARD = 0
+OFPMT_OXM = 1
+
+ofp_match_type_map = {
+    0: 'OFPMT_STANDARD',
+    1: 'OFPMT_OXM',
+}
+
+# Identifiers from group ofp_oxm_class
+OFPXMC_NXM_0 = 0
+OFPXMC_NXM_1 = 1
+OFPXMC_OPENFLOW_BASIC = 32768
+OFPXMC_EXPERIMENTER = 65535
+
+ofp_oxm_class_map = {
+    0: 'OFPXMC_NXM_0',
+    1: 'OFPXMC_NXM_1',
+    32768: 'OFPXMC_OPENFLOW_BASIC',
+    65535: 'OFPXMC_EXPERIMENTER',
+}
+
+# Identifiers from group ofp_packet_in_reason
+OFPR_NO_MATCH = 0
+OFPR_ACTION = 1
+OFPR_INVALID_TTL = 2
+
+ofp_packet_in_reason_map = {
+    0: 'OFPR_NO_MATCH',
+    1: 'OFPR_ACTION',
+    2: 'OFPR_INVALID_TTL',
+}
+
+# Identifiers from group ofp_port
+OFPP_MAX = 4294967040
+OFPP_IN_PORT = 4294967288
+OFPP_TABLE = 4294967289
+OFPP_NORMAL = 4294967290
+OFPP_FLOOD = 4294967291
+OFPP_ALL = 4294967292
+OFPP_CONTROLLER = 4294967293
+OFPP_LOCAL = 4294967294
+OFPP_ANY = 4294967295
+
+ofp_port_map = {
+    4294967040: 'OFPP_MAX',
+    4294967288: 'OFPP_IN_PORT',
+    4294967289: 'OFPP_TABLE',
+    4294967290: 'OFPP_NORMAL',
+    4294967291: 'OFPP_FLOOD',
+    4294967292: 'OFPP_ALL',
+    4294967293: 'OFPP_CONTROLLER',
+    4294967294: 'OFPP_LOCAL',
+    4294967295: 'OFPP_ANY',
+}
+
+# Identifiers from group ofp_port_config
+OFPPC_PORT_DOWN = 1
+OFPPC_NO_RECV = 4
+OFPPC_NO_FWD = 32
+OFPPC_NO_PACKET_IN = 64
+OFPPC_BSN_MIRROR_DEST = 2147483648
+
+ofp_port_config_map = {
+    1: 'OFPPC_PORT_DOWN',
+    4: 'OFPPC_NO_RECV',
+    32: 'OFPPC_NO_FWD',
+    64: 'OFPPC_NO_PACKET_IN',
+    2147483648: 'OFPPC_BSN_MIRROR_DEST',
+}
+
+# Identifiers from group ofp_port_features
+OFPPF_10MB_HD = 1
+OFPPF_10MB_FD = 2
+OFPPF_100MB_HD = 4
+OFPPF_100MB_FD = 8
+OFPPF_1GB_HD = 16
+OFPPF_1GB_FD = 32
+OFPPF_10GB_FD = 64
+OFPPF_40GB_FD = 128
+OFPPF_100GB_FD = 256
+OFPPF_1TB_FD = 512
+OFPPF_OTHER = 1024
+OFPPF_COPPER = 2048
+OFPPF_FIBER = 4096
+OFPPF_AUTONEG = 8192
+OFPPF_PAUSE = 16384
+OFPPF_PAUSE_ASYM = 32768
+
+ofp_port_features_map = {
+    1: 'OFPPF_10MB_HD',
+    2: 'OFPPF_10MB_FD',
+    4: 'OFPPF_100MB_HD',
+    8: 'OFPPF_100MB_FD',
+    16: 'OFPPF_1GB_HD',
+    32: 'OFPPF_1GB_FD',
+    64: 'OFPPF_10GB_FD',
+    128: 'OFPPF_40GB_FD',
+    256: 'OFPPF_100GB_FD',
+    512: 'OFPPF_1TB_FD',
+    1024: 'OFPPF_OTHER',
+    2048: 'OFPPF_COPPER',
+    4096: 'OFPPF_FIBER',
+    8192: 'OFPPF_AUTONEG',
+    16384: 'OFPPF_PAUSE',
+    32768: 'OFPPF_PAUSE_ASYM',
+}
+
+# Identifiers from group ofp_port_mod_failed_code
+OFPPMFC_BAD_PORT = 0
+OFPPMFC_BAD_HW_ADDR = 1
+OFPPMFC_BAD_CONFIG = 2
+OFPPMFC_BAD_ADVERTISE = 3
+OFPPMFC_EPERM = 4
+
+ofp_port_mod_failed_code_map = {
+    0: 'OFPPMFC_BAD_PORT',
+    1: 'OFPPMFC_BAD_HW_ADDR',
+    2: 'OFPPMFC_BAD_CONFIG',
+    3: 'OFPPMFC_BAD_ADVERTISE',
+    4: 'OFPPMFC_EPERM',
+}
+
+# Identifiers from group ofp_port_reason
+OFPPR_ADD = 0
+OFPPR_DELETE = 1
+OFPPR_MODIFY = 2
+
+ofp_port_reason_map = {
+    0: 'OFPPR_ADD',
+    1: 'OFPPR_DELETE',
+    2: 'OFPPR_MODIFY',
+}
+
+# Identifiers from group ofp_port_state
+OFPPS_LINK_DOWN = 1
+OFPPS_BLOCKED = 2
+OFPPS_LIVE = 4
+
+ofp_port_state_map = {
+    1: 'OFPPS_LINK_DOWN',
+    2: 'OFPPS_BLOCKED',
+    4: 'OFPPS_LIVE',
+}
+
+# Identifiers from group ofp_queue_op_failed_code
+OFPQOFC_BAD_PORT = 0
+OFPQOFC_BAD_QUEUE = 1
+OFPQOFC_EPERM = 2
+
+ofp_queue_op_failed_code_map = {
+    0: 'OFPQOFC_BAD_PORT',
+    1: 'OFPQOFC_BAD_QUEUE',
+    2: 'OFPQOFC_EPERM',
+}
+
+# Identifiers from group ofp_queue_properties
+OFPQT_MIN_RATE = 1
+OFPQT_MAX_RATE = 2
+OFPQT_EXPERIMENTER = 65535
+
+ofp_queue_properties_map = {
+    1: 'OFPQT_MIN_RATE',
+    2: 'OFPQT_MAX_RATE',
+    65535: 'OFPQT_EXPERIMENTER',
+}
+
+# Identifiers from group ofp_role_request_failed_code
+OFPRRFC_STALE = 0
+OFPRRFC_UNSUP = 1
+OFPRRFC_BAD_ROLE = 2
+
+ofp_role_request_failed_code_map = {
+    0: 'OFPRRFC_STALE',
+    1: 'OFPRRFC_UNSUP',
+    2: 'OFPRRFC_BAD_ROLE',
+}
+
+# Identifiers from group ofp_stats_reply_flags
+OFPSF_REPLY_MORE = 1
+
+ofp_stats_reply_flags_map = {
+    1: 'OFPSF_REPLY_MORE',
+}
+
+# Identifiers from group ofp_stats_request_flags
+
+ofp_stats_request_flags_map = {
+}
+
+# Identifiers from group ofp_stats_type
+OFPST_DESC = 0
+OFPST_FLOW = 1
+OFPST_AGGREGATE = 2
+OFPST_TABLE = 3
+OFPST_PORT = 4
+OFPST_QUEUE = 5
+OFPST_GROUP = 6
+OFPST_GROUP_DESC = 7
+OFPST_GROUP_FEATURES = 8
+OFPST_EXPERIMENTER = 65535
+
+ofp_stats_type_map = {
+    0: 'OFPST_DESC',
+    1: 'OFPST_FLOW',
+    2: 'OFPST_AGGREGATE',
+    3: 'OFPST_TABLE',
+    4: 'OFPST_PORT',
+    5: 'OFPST_QUEUE',
+    6: 'OFPST_GROUP',
+    7: 'OFPST_GROUP_DESC',
+    8: 'OFPST_GROUP_FEATURES',
+    65535: 'OFPST_EXPERIMENTER',
+}
+
+# Identifiers from group ofp_switch_config_failed_code
+OFPSCFC_BAD_FLAGS = 0
+OFPSCFC_BAD_LEN = 1
+OFPSCFC_EPERM = 2
+
+ofp_switch_config_failed_code_map = {
+    0: 'OFPSCFC_BAD_FLAGS',
+    1: 'OFPSCFC_BAD_LEN',
+    2: 'OFPSCFC_EPERM',
+}
+
+# Identifiers from group ofp_table
+OFPTT_MAX = 254
+OFPTT_ALL = 255
+
+ofp_table_map = {
+    254: 'OFPTT_MAX',
+    255: 'OFPTT_ALL',
+}
+
+# Identifiers from group ofp_table_config
+OFPTC_TABLE_MISS_CONTROLLER = 0
+OFPTC_TABLE_MISS_CONTINUE = 1
+OFPTC_TABLE_MISS_DROP = 2
+OFPTC_TABLE_MISS_MASK = 3
+
+ofp_table_config_map = {
+    0: 'OFPTC_TABLE_MISS_CONTROLLER',
+    1: 'OFPTC_TABLE_MISS_CONTINUE',
+    2: 'OFPTC_TABLE_MISS_DROP',
+    3: 'OFPTC_TABLE_MISS_MASK',
+}
+
+# Identifiers from group ofp_table_mod_failed_code
+OFPTMFC_BAD_TABLE = 0
+OFPTMFC_BAD_CONFIG = 1
+OFPTMFC_EPERM = 2
+
+ofp_table_mod_failed_code_map = {
+    0: 'OFPTMFC_BAD_TABLE',
+    1: 'OFPTMFC_BAD_CONFIG',
+    2: 'OFPTMFC_EPERM',
+}
+
+# Identifiers from group ofp_type
+OFPT_HELLO = 0
+OFPT_ERROR = 1
+OFPT_ECHO_REQUEST = 2
+OFPT_ECHO_REPLY = 3
+OFPT_EXPERIMENTER = 4
+OFPT_FEATURES_REQUEST = 5
+OFPT_FEATURES_REPLY = 6
+OFPT_GET_CONFIG_REQUEST = 7
+OFPT_GET_CONFIG_REPLY = 8
+OFPT_SET_CONFIG = 9
+OFPT_PACKET_IN = 10
+OFPT_FLOW_REMOVED = 11
+OFPT_PORT_STATUS = 12
+OFPT_PACKET_OUT = 13
+OFPT_FLOW_MOD = 14
+OFPT_GROUP_MOD = 15
+OFPT_PORT_MOD = 16
+OFPT_TABLE_MOD = 17
+OFPT_STATS_REQUEST = 18
+OFPT_STATS_REPLY = 19
+OFPT_BARRIER_REQUEST = 20
+OFPT_BARRIER_REPLY = 21
+OFPT_QUEUE_GET_CONFIG_REQUEST = 22
+OFPT_QUEUE_GET_CONFIG_REPLY = 23
+OFPT_ROLE_REQUEST = 24
+OFPT_ROLE_REPLY = 25
+
+ofp_type_map = {
+    0: 'OFPT_HELLO',
+    1: 'OFPT_ERROR',
+    2: 'OFPT_ECHO_REQUEST',
+    3: 'OFPT_ECHO_REPLY',
+    4: 'OFPT_EXPERIMENTER',
+    5: 'OFPT_FEATURES_REQUEST',
+    6: 'OFPT_FEATURES_REPLY',
+    7: 'OFPT_GET_CONFIG_REQUEST',
+    8: 'OFPT_GET_CONFIG_REPLY',
+    9: 'OFPT_SET_CONFIG',
+    10: 'OFPT_PACKET_IN',
+    11: 'OFPT_FLOW_REMOVED',
+    12: 'OFPT_PORT_STATUS',
+    13: 'OFPT_PACKET_OUT',
+    14: 'OFPT_FLOW_MOD',
+    15: 'OFPT_GROUP_MOD',
+    16: 'OFPT_PORT_MOD',
+    17: 'OFPT_TABLE_MOD',
+    18: 'OFPT_STATS_REQUEST',
+    19: 'OFPT_STATS_REPLY',
+    20: 'OFPT_BARRIER_REQUEST',
+    21: 'OFPT_BARRIER_REPLY',
+    22: 'OFPT_QUEUE_GET_CONFIG_REQUEST',
+    23: 'OFPT_QUEUE_GET_CONFIG_REPLY',
+    24: 'OFPT_ROLE_REQUEST',
+    25: 'OFPT_ROLE_REPLY',
+}
+
+# Identifiers from group ofp_vlan_id
+OFPVID_NONE = 0
+OFPVID_PRESENT = 4096
+
+ofp_vlan_id_map = {
+    0: 'OFPVID_NONE',
+    4096: 'OFPVID_PRESENT',
+}
+
diff --git a/Fabric/Utilities/src/python/loxi/of12/instruction.py b/Fabric/Utilities/src/python/loxi/of12/instruction.py
new file mode 100644
index 0000000..4999e3e
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of12/instruction.py
@@ -0,0 +1,389 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of12']
+
+class instruction(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = instruction.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = instruction()
+        obj.type = reader.read("!H")[0]
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("instruction {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class apply_actions(instruction):
+    type = 4
+
+    def __init__(self, actions=None):
+        if actions != None:
+            self.actions = actions
+        else:
+            self.actions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.actions))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = apply_actions()
+        _type = reader.read("!H")[0]
+        assert(_type == 4)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        obj.actions = loxi.generic_util.unpack_list(reader, ofp.action.action.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.actions != other.actions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("apply_actions {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("actions = ");
+                q.pp(self.actions)
+            q.breakable()
+        q.text('}')
+
+instruction.subtypes[4] = apply_actions
+
+class clear_actions(instruction):
+    type = 5
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = clear_actions()
+        _type = reader.read("!H")[0]
+        assert(_type == 5)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("clear_actions {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+instruction.subtypes[5] = clear_actions
+
+class experimenter(instruction):
+    subtypes = {}
+
+    type = 65535
+
+    def __init__(self, experimenter=None, data=None):
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 4)
+        subclass = experimenter.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = experimenter()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.experimenter = reader.read("!L")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.experimenter != other.experimenter: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+instruction.subtypes[65535] = experimenter
+
+class goto_table(instruction):
+    type = 1
+
+    def __init__(self, table_id=None):
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = goto_table()
+        _type = reader.read("!H")[0]
+        assert(_type == 1)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.table_id = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.table_id != other.table_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("goto_table {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+            q.breakable()
+        q.text('}')
+
+instruction.subtypes[1] = goto_table
+
+class write_actions(instruction):
+    type = 3
+
+    def __init__(self, actions=None):
+        if actions != None:
+            self.actions = actions
+        else:
+            self.actions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.actions))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = write_actions()
+        _type = reader.read("!H")[0]
+        assert(_type == 3)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        obj.actions = loxi.generic_util.unpack_list(reader, ofp.action.action.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.actions != other.actions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("write_actions {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("actions = ");
+                q.pp(self.actions)
+            q.breakable()
+        q.text('}')
+
+instruction.subtypes[3] = write_actions
+
+class write_metadata(instruction):
+    type = 2
+
+    def __init__(self, metadata=None, metadata_mask=None):
+        if metadata != None:
+            self.metadata = metadata
+        else:
+            self.metadata = 0
+        if metadata_mask != None:
+            self.metadata_mask = metadata_mask
+        else:
+            self.metadata_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!Q", self.metadata))
+        packed.append(struct.pack("!Q", self.metadata_mask))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = write_metadata()
+        _type = reader.read("!H")[0]
+        assert(_type == 2)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        obj.metadata = reader.read("!Q")[0]
+        obj.metadata_mask = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.metadata != other.metadata: return False
+        if self.metadata_mask != other.metadata_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("write_metadata {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("metadata = ");
+                q.text("%#x" % self.metadata)
+                q.text(","); q.breakable()
+                q.text("metadata_mask = ");
+                q.text("%#x" % self.metadata_mask)
+            q.breakable()
+        q.text('}')
+
+instruction.subtypes[2] = write_metadata
+
+
diff --git a/Fabric/Utilities/src/python/loxi/of12/message.py b/Fabric/Utilities/src/python/loxi/of12/message.py
new file mode 100644
index 0000000..c4f0ecb
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of12/message.py
@@ -0,0 +1,8443 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of12']
+
+class message(loxi.OFObject):
+    subtypes = {}
+
+    version = 3
+
+    def __init__(self, type=None, xid=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('B', 1)
+        subclass = message.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = message()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        obj.type = reader.read("!B")[0]
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("message {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+
+class stats_reply(message):
+    subtypes = {}
+
+    version = 3
+    type = 19
+
+    def __init__(self, xid=None, stats_type=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if stats_type != None:
+            self.stats_type = stats_type
+        else:
+            self.stats_type = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 8)
+        subclass = stats_reply.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.stats_type = reader.read("!H")[0]
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.stats_type != other.stats_type: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[19] = stats_reply
+
+class aggregate_stats_reply(stats_reply):
+    version = 3
+    type = 19
+    stats_type = 2
+
+    def __init__(self, xid=None, flags=None, packet_count=None, byte_count=None, flow_count=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if packet_count != None:
+            self.packet_count = packet_count
+        else:
+            self.packet_count = 0
+        if byte_count != None:
+            self.byte_count = byte_count
+        else:
+            self.byte_count = 0
+        if flow_count != None:
+            self.flow_count = flow_count
+        else:
+            self.flow_count = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!Q", self.packet_count))
+        packed.append(struct.pack("!Q", self.byte_count))
+        packed.append(struct.pack("!L", self.flow_count))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = aggregate_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 2)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.packet_count = reader.read("!Q")[0]
+        obj.byte_count = reader.read("!Q")[0]
+        obj.flow_count = reader.read("!L")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.packet_count != other.packet_count: return False
+        if self.byte_count != other.byte_count: return False
+        if self.flow_count != other.flow_count: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("aggregate_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("packet_count = ");
+                q.text("%#x" % self.packet_count)
+                q.text(","); q.breakable()
+                q.text("byte_count = ");
+                q.text("%#x" % self.byte_count)
+                q.text(","); q.breakable()
+                q.text("flow_count = ");
+                q.text("%#x" % self.flow_count)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[2] = aggregate_stats_reply
+
+class stats_request(message):
+    subtypes = {}
+
+    version = 3
+    type = 18
+
+    def __init__(self, xid=None, stats_type=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if stats_type != None:
+            self.stats_type = stats_type
+        else:
+            self.stats_type = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 8)
+        subclass = stats_request.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.stats_type = reader.read("!H")[0]
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.stats_type != other.stats_type: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[18] = stats_request
+
+class aggregate_stats_request(stats_request):
+    version = 3
+    type = 18
+    stats_type = 2
+
+    def __init__(self, xid=None, flags=None, table_id=None, out_port=None, out_group=None, cookie=None, cookie_mask=None, match=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if out_group != None:
+            self.out_group = out_group
+        else:
+            self.out_group = 0
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if cookie_mask != None:
+            self.cookie_mask = cookie_mask
+        else:
+            self.cookie_mask = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append('\x00' * 3)
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!L", self.out_group))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.cookie_mask))
+        packed.append(self.match.pack())
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = aggregate_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 2)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.table_id = reader.read("!B")[0]
+        reader.skip(3)
+        obj.out_port = util.unpack_port_no(reader)
+        obj.out_group = reader.read("!L")[0]
+        reader.skip(4)
+        obj.cookie = reader.read("!Q")[0]
+        obj.cookie_mask = reader.read("!Q")[0]
+        obj.match = ofp.match.unpack(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.table_id != other.table_id: return False
+        if self.out_port != other.out_port: return False
+        if self.out_group != other.out_group: return False
+        if self.cookie != other.cookie: return False
+        if self.cookie_mask != other.cookie_mask: return False
+        if self.match != other.match: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("aggregate_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("out_group = ");
+                q.text("%#x" % self.out_group)
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("cookie_mask = ");
+                q.text("%#x" % self.cookie_mask)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[2] = aggregate_stats_request
+
+class error_msg(message):
+    subtypes = {}
+
+    version = 3
+    type = 1
+
+    def __init__(self, xid=None, err_type=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if err_type != None:
+            self.err_type = err_type
+        else:
+            self.err_type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 8)
+        subclass = error_msg.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.err_type = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.err_type != other.err_type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+message.subtypes[1] = error_msg
+
+class bad_action_error_msg(error_msg):
+    version = 3
+    type = 1
+    err_type = 2
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bad_action_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 2)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bad_action_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[2] = bad_action_error_msg
+
+class bad_instruction_error_msg(error_msg):
+    version = 3
+    type = 1
+    err_type = 3
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bad_instruction_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 3)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bad_instruction_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[3] = bad_instruction_error_msg
+
+class bad_match_error_msg(error_msg):
+    version = 3
+    type = 1
+    err_type = 4
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bad_match_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 4)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bad_match_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[4] = bad_match_error_msg
+
+class bad_request_error_msg(error_msg):
+    version = 3
+    type = 1
+    err_type = 1
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bad_request_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 1)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bad_request_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[1] = bad_request_error_msg
+
+class barrier_reply(message):
+    version = 3
+    type = 21
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = barrier_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 21)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("barrier_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+message.subtypes[21] = barrier_reply
+
+class barrier_request(message):
+    version = 3
+    type = 20
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = barrier_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 20)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("barrier_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+message.subtypes[20] = barrier_request
+
+class experimenter(message):
+    subtypes = {}
+
+    version = 3
+    type = 4
+
+    def __init__(self, xid=None, experimenter=None, subtype=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 8)
+        subclass = experimenter.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = experimenter()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.experimenter = reader.read("!L")[0]
+        obj.subtype = reader.read("!L")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.experimenter != other.experimenter: return False
+        if self.subtype != other.subtype: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("subtype = ");
+                q.text("%#x" % self.subtype)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[4] = experimenter
+
+class bsn_header(experimenter):
+    subtypes = {}
+
+    version = 3
+    type = 4
+    experimenter = 6035143
+
+    def __init__(self, xid=None, subtype=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 12)
+        subclass = bsn_header.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = bsn_header()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        obj.subtype = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_header {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+experimenter.subtypes[6035143] = bsn_header
+
+class bsn_bw_clear_data_reply(bsn_header):
+    version = 3
+    type = 4
+    experimenter = 6035143
+    subtype = 22
+
+    def __init__(self, xid=None, status=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.status))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_bw_clear_data_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 22)
+        obj.status = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.status != other.status: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_bw_clear_data_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[22] = bsn_bw_clear_data_reply
+
+class bsn_bw_clear_data_request(bsn_header):
+    version = 3
+    type = 4
+    experimenter = 6035143
+    subtype = 21
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_bw_clear_data_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 21)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_bw_clear_data_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[21] = bsn_bw_clear_data_request
+
+class bsn_bw_enable_get_reply(bsn_header):
+    version = 3
+    type = 4
+    experimenter = 6035143
+    subtype = 20
+
+    def __init__(self, xid=None, enabled=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if enabled != None:
+            self.enabled = enabled
+        else:
+            self.enabled = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.enabled))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_bw_enable_get_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 20)
+        obj.enabled = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.enabled != other.enabled: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_bw_enable_get_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("enabled = ");
+                q.text("%#x" % self.enabled)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[20] = bsn_bw_enable_get_reply
+
+class bsn_bw_enable_get_request(bsn_header):
+    version = 3
+    type = 4
+    experimenter = 6035143
+    subtype = 19
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_bw_enable_get_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 19)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_bw_enable_get_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[19] = bsn_bw_enable_get_request
+
+class bsn_bw_enable_set_reply(bsn_header):
+    version = 3
+    type = 4
+    experimenter = 6035143
+    subtype = 23
+
+    def __init__(self, xid=None, enable=None, status=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if enable != None:
+            self.enable = enable
+        else:
+            self.enable = 0
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.enable))
+        packed.append(struct.pack("!L", self.status))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_bw_enable_set_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 23)
+        obj.enable = reader.read("!L")[0]
+        obj.status = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.enable != other.enable: return False
+        if self.status != other.status: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_bw_enable_set_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("enable = ");
+                q.text("%#x" % self.enable)
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[23] = bsn_bw_enable_set_reply
+
+class bsn_bw_enable_set_request(bsn_header):
+    version = 3
+    type = 4
+    experimenter = 6035143
+    subtype = 18
+
+    def __init__(self, xid=None, enable=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if enable != None:
+            self.enable = enable
+        else:
+            self.enable = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.enable))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_bw_enable_set_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 18)
+        obj.enable = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.enable != other.enable: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_bw_enable_set_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("enable = ");
+                q.text("%#x" % self.enable)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[18] = bsn_bw_enable_set_request
+
+class bsn_get_interfaces_reply(bsn_header):
+    version = 3
+    type = 4
+    experimenter = 6035143
+    subtype = 10
+
+    def __init__(self, xid=None, interfaces=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if interfaces != None:
+            self.interfaces = interfaces
+        else:
+            self.interfaces = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.interfaces))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_get_interfaces_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 10)
+        obj.interfaces = loxi.generic_util.unpack_list(reader, ofp.common.bsn_interface.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.interfaces != other.interfaces: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_get_interfaces_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("interfaces = ");
+                q.pp(self.interfaces)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[10] = bsn_get_interfaces_reply
+
+class bsn_get_interfaces_request(bsn_header):
+    version = 3
+    type = 4
+    experimenter = 6035143
+    subtype = 9
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_get_interfaces_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 9)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_get_interfaces_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[9] = bsn_get_interfaces_request
+
+class bsn_get_mirroring_reply(bsn_header):
+    version = 3
+    type = 4
+    experimenter = 6035143
+    subtype = 5
+
+    def __init__(self, xid=None, report_mirror_ports=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if report_mirror_ports != None:
+            self.report_mirror_ports = report_mirror_ports
+        else:
+            self.report_mirror_ports = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!B", self.report_mirror_ports))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_get_mirroring_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 5)
+        obj.report_mirror_ports = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.report_mirror_ports != other.report_mirror_ports: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_get_mirroring_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("report_mirror_ports = ");
+                q.text("%#x" % self.report_mirror_ports)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[5] = bsn_get_mirroring_reply
+
+class bsn_get_mirroring_request(bsn_header):
+    version = 3
+    type = 4
+    experimenter = 6035143
+    subtype = 4
+
+    def __init__(self, xid=None, report_mirror_ports=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if report_mirror_ports != None:
+            self.report_mirror_ports = report_mirror_ports
+        else:
+            self.report_mirror_ports = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!B", self.report_mirror_ports))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_get_mirroring_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 4)
+        obj.report_mirror_ports = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.report_mirror_ports != other.report_mirror_ports: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_get_mirroring_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("report_mirror_ports = ");
+                q.text("%#x" % self.report_mirror_ports)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[4] = bsn_get_mirroring_request
+
+class bsn_pdu_rx_reply(bsn_header):
+    version = 3
+    type = 4
+    experimenter = 6035143
+    subtype = 34
+
+    def __init__(self, xid=None, status=None, port_no=None, slot_num=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if slot_num != None:
+            self.slot_num = slot_num
+        else:
+            self.slot_num = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.status))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!B", self.slot_num))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_pdu_rx_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 34)
+        obj.status = reader.read("!L")[0]
+        obj.port_no = util.unpack_port_no(reader)
+        obj.slot_num = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.status != other.status: return False
+        if self.port_no != other.port_no: return False
+        if self.slot_num != other.slot_num: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_pdu_rx_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("slot_num = ");
+                q.text("%#x" % self.slot_num)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[34] = bsn_pdu_rx_reply
+
+class bsn_pdu_rx_request(bsn_header):
+    version = 3
+    type = 4
+    experimenter = 6035143
+    subtype = 33
+
+    def __init__(self, xid=None, timeout_ms=None, port_no=None, slot_num=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if timeout_ms != None:
+            self.timeout_ms = timeout_ms
+        else:
+            self.timeout_ms = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if slot_num != None:
+            self.slot_num = slot_num
+        else:
+            self.slot_num = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.timeout_ms))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!B", self.slot_num))
+        packed.append('\x00' * 3)
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_pdu_rx_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 33)
+        obj.timeout_ms = reader.read("!L")[0]
+        obj.port_no = util.unpack_port_no(reader)
+        obj.slot_num = reader.read("!B")[0]
+        reader.skip(3)
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.timeout_ms != other.timeout_ms: return False
+        if self.port_no != other.port_no: return False
+        if self.slot_num != other.slot_num: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_pdu_rx_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("timeout_ms = ");
+                q.text("%#x" % self.timeout_ms)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("slot_num = ");
+                q.text("%#x" % self.slot_num)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[33] = bsn_pdu_rx_request
+
+class bsn_pdu_rx_timeout(bsn_header):
+    version = 3
+    type = 4
+    experimenter = 6035143
+    subtype = 35
+
+    def __init__(self, xid=None, port_no=None, slot_num=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if slot_num != None:
+            self.slot_num = slot_num
+        else:
+            self.slot_num = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!B", self.slot_num))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_pdu_rx_timeout()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 35)
+        obj.port_no = util.unpack_port_no(reader)
+        obj.slot_num = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.port_no != other.port_no: return False
+        if self.slot_num != other.slot_num: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_pdu_rx_timeout {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("slot_num = ");
+                q.text("%#x" % self.slot_num)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[35] = bsn_pdu_rx_timeout
+
+class bsn_pdu_tx_reply(bsn_header):
+    version = 3
+    type = 4
+    experimenter = 6035143
+    subtype = 32
+
+    def __init__(self, xid=None, status=None, port_no=None, slot_num=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if slot_num != None:
+            self.slot_num = slot_num
+        else:
+            self.slot_num = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.status))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!B", self.slot_num))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_pdu_tx_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 32)
+        obj.status = reader.read("!L")[0]
+        obj.port_no = util.unpack_port_no(reader)
+        obj.slot_num = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.status != other.status: return False
+        if self.port_no != other.port_no: return False
+        if self.slot_num != other.slot_num: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_pdu_tx_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("slot_num = ");
+                q.text("%#x" % self.slot_num)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[32] = bsn_pdu_tx_reply
+
+class bsn_pdu_tx_request(bsn_header):
+    version = 3
+    type = 4
+    experimenter = 6035143
+    subtype = 31
+
+    def __init__(self, xid=None, tx_interval_ms=None, port_no=None, slot_num=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if tx_interval_ms != None:
+            self.tx_interval_ms = tx_interval_ms
+        else:
+            self.tx_interval_ms = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if slot_num != None:
+            self.slot_num = slot_num
+        else:
+            self.slot_num = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.tx_interval_ms))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!B", self.slot_num))
+        packed.append('\x00' * 3)
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_pdu_tx_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 31)
+        obj.tx_interval_ms = reader.read("!L")[0]
+        obj.port_no = util.unpack_port_no(reader)
+        obj.slot_num = reader.read("!B")[0]
+        reader.skip(3)
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.tx_interval_ms != other.tx_interval_ms: return False
+        if self.port_no != other.port_no: return False
+        if self.slot_num != other.slot_num: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_pdu_tx_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("tx_interval_ms = ");
+                q.text("%#x" % self.tx_interval_ms)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("slot_num = ");
+                q.text("%#x" % self.slot_num)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[31] = bsn_pdu_tx_request
+
+class bsn_set_mirroring(bsn_header):
+    version = 3
+    type = 4
+    experimenter = 6035143
+    subtype = 3
+
+    def __init__(self, xid=None, report_mirror_ports=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if report_mirror_ports != None:
+            self.report_mirror_ports = report_mirror_ports
+        else:
+            self.report_mirror_ports = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!B", self.report_mirror_ports))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_mirroring()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 3)
+        obj.report_mirror_ports = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.report_mirror_ports != other.report_mirror_ports: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_mirroring {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("report_mirror_ports = ");
+                q.text("%#x" % self.report_mirror_ports)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[3] = bsn_set_mirroring
+
+class bsn_set_pktin_suppression_reply(bsn_header):
+    version = 3
+    type = 4
+    experimenter = 6035143
+    subtype = 25
+
+    def __init__(self, xid=None, status=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.status))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_pktin_suppression_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 25)
+        obj.status = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.status != other.status: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_pktin_suppression_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[25] = bsn_set_pktin_suppression_reply
+
+class bsn_set_pktin_suppression_request(bsn_header):
+    version = 3
+    type = 4
+    experimenter = 6035143
+    subtype = 11
+
+    def __init__(self, xid=None, enabled=None, idle_timeout=None, hard_timeout=None, priority=None, cookie=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if enabled != None:
+            self.enabled = enabled
+        else:
+            self.enabled = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!B", self.enabled))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!Q", self.cookie))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_pktin_suppression_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 11)
+        obj.enabled = reader.read("!B")[0]
+        reader.skip(1)
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.cookie = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.enabled != other.enabled: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.priority != other.priority: return False
+        if self.cookie != other.cookie: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_pktin_suppression_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("enabled = ");
+                q.text("%#x" % self.enabled)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[11] = bsn_set_pktin_suppression_request
+
+class experimenter_stats_reply(stats_reply):
+    subtypes = {}
+
+    version = 3
+    type = 19
+    stats_type = 65535
+
+    def __init__(self, xid=None, flags=None, experimenter=None, subtype=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 16)
+        subclass = experimenter_stats_reply.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = experimenter_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.experimenter = reader.read("!L")[0]
+        obj.subtype = reader.read("!L")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.experimenter != other.experimenter: return False
+        if self.subtype != other.subtype: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("subtype = ");
+                q.text("%#x" % self.subtype)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[65535] = experimenter_stats_reply
+
+class bsn_stats_reply(experimenter_stats_reply):
+    subtypes = {}
+
+    version = 3
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+
+    def __init__(self, xid=None, flags=None, subtype=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 20)
+        subclass = bsn_stats_reply.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = bsn_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        obj.subtype = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+experimenter_stats_reply.subtypes[6035143] = bsn_stats_reply
+
+class experimenter_stats_request(stats_request):
+    subtypes = {}
+
+    version = 3
+    type = 18
+    stats_type = 65535
+
+    def __init__(self, xid=None, flags=None, experimenter=None, subtype=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 16)
+        subclass = experimenter_stats_request.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = experimenter_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.experimenter = reader.read("!L")[0]
+        obj.subtype = reader.read("!L")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.experimenter != other.experimenter: return False
+        if self.subtype != other.subtype: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("subtype = ");
+                q.text("%#x" % self.subtype)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[65535] = experimenter_stats_request
+
+class bsn_stats_request(experimenter_stats_request):
+    subtypes = {}
+
+    version = 3
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+
+    def __init__(self, xid=None, flags=None, subtype=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 20)
+        subclass = bsn_stats_request.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = bsn_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        obj.subtype = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+experimenter_stats_request.subtypes[6035143] = bsn_stats_request
+
+class bsn_virtual_port_create_reply(bsn_header):
+    version = 3
+    type = 4
+    experimenter = 6035143
+    subtype = 16
+
+    def __init__(self, xid=None, status=None, vport_no=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        if vport_no != None:
+            self.vport_no = vport_no
+        else:
+            self.vport_no = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.status))
+        packed.append(struct.pack("!L", self.vport_no))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_virtual_port_create_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 16)
+        obj.status = reader.read("!L")[0]
+        obj.vport_no = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.status != other.status: return False
+        if self.vport_no != other.vport_no: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_virtual_port_create_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+                q.text(","); q.breakable()
+                q.text("vport_no = ");
+                q.text("%#x" % self.vport_no)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[16] = bsn_virtual_port_create_reply
+
+class bsn_virtual_port_create_request(bsn_header):
+    version = 3
+    type = 4
+    experimenter = 6035143
+    subtype = 15
+
+    def __init__(self, xid=None, vport=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if vport != None:
+            self.vport = vport
+        else:
+            self.vport = ofp.bsn_vport()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(self.vport.pack())
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_virtual_port_create_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 15)
+        obj.vport = ofp.bsn_vport.unpack(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.vport != other.vport: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_virtual_port_create_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("vport = ");
+                q.pp(self.vport)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[15] = bsn_virtual_port_create_request
+
+class bsn_virtual_port_remove_reply(bsn_header):
+    version = 3
+    type = 4
+    experimenter = 6035143
+    subtype = 26
+
+    def __init__(self, xid=None, status=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.status))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_virtual_port_remove_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 26)
+        obj.status = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.status != other.status: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_virtual_port_remove_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[26] = bsn_virtual_port_remove_reply
+
+class bsn_virtual_port_remove_request(bsn_header):
+    version = 3
+    type = 4
+    experimenter = 6035143
+    subtype = 17
+
+    def __init__(self, xid=None, vport_no=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if vport_no != None:
+            self.vport_no = vport_no
+        else:
+            self.vport_no = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.vport_no))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_virtual_port_remove_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 17)
+        obj.vport_no = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.vport_no != other.vport_no: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_virtual_port_remove_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("vport_no = ");
+                q.text("%#x" % self.vport_no)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[17] = bsn_virtual_port_remove_request
+
+class desc_stats_reply(stats_reply):
+    version = 3
+    type = 19
+    stats_type = 0
+
+    def __init__(self, xid=None, flags=None, mfr_desc=None, hw_desc=None, sw_desc=None, serial_num=None, dp_desc=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if mfr_desc != None:
+            self.mfr_desc = mfr_desc
+        else:
+            self.mfr_desc = ""
+        if hw_desc != None:
+            self.hw_desc = hw_desc
+        else:
+            self.hw_desc = ""
+        if sw_desc != None:
+            self.sw_desc = sw_desc
+        else:
+            self.sw_desc = ""
+        if serial_num != None:
+            self.serial_num = serial_num
+        else:
+            self.serial_num = ""
+        if dp_desc != None:
+            self.dp_desc = dp_desc
+        else:
+            self.dp_desc = ""
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!256s", self.mfr_desc))
+        packed.append(struct.pack("!256s", self.hw_desc))
+        packed.append(struct.pack("!256s", self.sw_desc))
+        packed.append(struct.pack("!32s", self.serial_num))
+        packed.append(struct.pack("!256s", self.dp_desc))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = desc_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 0)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.mfr_desc = reader.read("!256s")[0].rstrip("\x00")
+        obj.hw_desc = reader.read("!256s")[0].rstrip("\x00")
+        obj.sw_desc = reader.read("!256s")[0].rstrip("\x00")
+        obj.serial_num = reader.read("!32s")[0].rstrip("\x00")
+        obj.dp_desc = reader.read("!256s")[0].rstrip("\x00")
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.mfr_desc != other.mfr_desc: return False
+        if self.hw_desc != other.hw_desc: return False
+        if self.sw_desc != other.sw_desc: return False
+        if self.serial_num != other.serial_num: return False
+        if self.dp_desc != other.dp_desc: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("desc_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("mfr_desc = ");
+                q.pp(self.mfr_desc)
+                q.text(","); q.breakable()
+                q.text("hw_desc = ");
+                q.pp(self.hw_desc)
+                q.text(","); q.breakable()
+                q.text("sw_desc = ");
+                q.pp(self.sw_desc)
+                q.text(","); q.breakable()
+                q.text("serial_num = ");
+                q.pp(self.serial_num)
+                q.text(","); q.breakable()
+                q.text("dp_desc = ");
+                q.pp(self.dp_desc)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[0] = desc_stats_reply
+
+class desc_stats_request(stats_request):
+    version = 3
+    type = 18
+    stats_type = 0
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = desc_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 0)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("desc_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[0] = desc_stats_request
+
+class echo_reply(message):
+    version = 3
+    type = 3
+
+    def __init__(self, xid=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = echo_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 3)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("echo_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[3] = echo_reply
+
+class echo_request(message):
+    version = 3
+    type = 2
+
+    def __init__(self, xid=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = echo_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 2)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("echo_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[2] = echo_request
+
+class experimenter_error_msg(error_msg):
+    version = 3
+    type = 1
+    err_type = 65535
+
+    def __init__(self, xid=None, subtype=None, experimenter=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.subtype))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = experimenter_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 65535)
+        obj.subtype = reader.read("!H")[0]
+        obj.experimenter = reader.read("!L")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.subtype != other.subtype: return False
+        if self.experimenter != other.experimenter: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("subtype = ");
+                q.text("%#x" % self.subtype)
+                q.text(","); q.breakable()
+                q.text("experimenter = ");
+                q.text("%#x" % self.experimenter)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[65535] = experimenter_error_msg
+
+class features_reply(message):
+    version = 3
+    type = 6
+
+    def __init__(self, xid=None, datapath_id=None, n_buffers=None, n_tables=None, capabilities=None, reserved=None, ports=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if datapath_id != None:
+            self.datapath_id = datapath_id
+        else:
+            self.datapath_id = 0
+        if n_buffers != None:
+            self.n_buffers = n_buffers
+        else:
+            self.n_buffers = 0
+        if n_tables != None:
+            self.n_tables = n_tables
+        else:
+            self.n_tables = 0
+        if capabilities != None:
+            self.capabilities = capabilities
+        else:
+            self.capabilities = 0
+        if reserved != None:
+            self.reserved = reserved
+        else:
+            self.reserved = 0
+        if ports != None:
+            self.ports = ports
+        else:
+            self.ports = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!Q", self.datapath_id))
+        packed.append(struct.pack("!L", self.n_buffers))
+        packed.append(struct.pack("!B", self.n_tables))
+        packed.append('\x00' * 3)
+        packed.append(struct.pack("!L", self.capabilities))
+        packed.append(struct.pack("!L", self.reserved))
+        packed.append(loxi.generic_util.pack_list(self.ports))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = features_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 6)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.datapath_id = reader.read("!Q")[0]
+        obj.n_buffers = reader.read("!L")[0]
+        obj.n_tables = reader.read("!B")[0]
+        reader.skip(3)
+        obj.capabilities = reader.read("!L")[0]
+        obj.reserved = reader.read("!L")[0]
+        obj.ports = loxi.generic_util.unpack_list(reader, ofp.common.port_desc.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.datapath_id != other.datapath_id: return False
+        if self.n_buffers != other.n_buffers: return False
+        if self.n_tables != other.n_tables: return False
+        if self.capabilities != other.capabilities: return False
+        if self.reserved != other.reserved: return False
+        if self.ports != other.ports: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("features_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("datapath_id = ");
+                q.text("%#x" % self.datapath_id)
+                q.text(","); q.breakable()
+                q.text("n_buffers = ");
+                q.text("%#x" % self.n_buffers)
+                q.text(","); q.breakable()
+                q.text("n_tables = ");
+                q.text("%#x" % self.n_tables)
+                q.text(","); q.breakable()
+                q.text("capabilities = ");
+                q.text("%#x" % self.capabilities)
+                q.text(","); q.breakable()
+                q.text("reserved = ");
+                q.text("%#x" % self.reserved)
+                q.text(","); q.breakable()
+                q.text("ports = ");
+                q.pp(self.ports)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[6] = features_reply
+
+class features_request(message):
+    version = 3
+    type = 5
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = features_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 5)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("features_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+message.subtypes[5] = features_request
+
+class flow_mod(message):
+    subtypes = {}
+
+    version = 3
+    type = 14
+
+    def __init__(self, xid=None, cookie=None, cookie_mask=None, table_id=None, _command=None, idle_timeout=None, hard_timeout=None, priority=None, buffer_id=None, out_port=None, out_group=None, flags=None, match=None, instructions=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if cookie_mask != None:
+            self.cookie_mask = cookie_mask
+        else:
+            self.cookie_mask = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if _command != None:
+            self._command = _command
+        else:
+            self._command = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if out_group != None:
+            self.out_group = out_group
+        else:
+            self.out_group = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if instructions != None:
+            self.instructions = instructions
+        else:
+            self.instructions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.cookie_mask))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append(util.pack_fm_cmd(self._command))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!L", self.out_group))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 2)
+        packed.append(self.match.pack())
+        packed.append(loxi.generic_util.pack_list(self.instructions))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('B', 25)
+        subclass = flow_mod.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = flow_mod()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 14)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.cookie = reader.read("!Q")[0]
+        obj.cookie_mask = reader.read("!Q")[0]
+        obj.table_id = reader.read("!B")[0]
+        obj._command = util.unpack_fm_cmd(reader)
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.out_port = util.unpack_port_no(reader)
+        obj.out_group = reader.read("!L")[0]
+        obj.flags = reader.read("!H")[0]
+        reader.skip(2)
+        obj.match = ofp.match.unpack(reader)
+        obj.instructions = loxi.generic_util.unpack_list(reader, ofp.instruction.instruction.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.cookie != other.cookie: return False
+        if self.cookie_mask != other.cookie_mask: return False
+        if self.table_id != other.table_id: return False
+        if self._command != other._command: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.priority != other.priority: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.out_port != other.out_port: return False
+        if self.out_group != other.out_group: return False
+        if self.flags != other.flags: return False
+        if self.match != other.match: return False
+        if self.instructions != other.instructions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_mod {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("cookie_mask = ");
+                q.text("%#x" % self.cookie_mask)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("out_group = ");
+                q.text("%#x" % self.out_group)
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("instructions = ");
+                q.pp(self.instructions)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[14] = flow_mod
+
+class flow_add(flow_mod):
+    version = 3
+    type = 14
+    _command = 0
+
+    def __init__(self, xid=None, cookie=None, cookie_mask=None, table_id=None, idle_timeout=None, hard_timeout=None, priority=None, buffer_id=None, out_port=None, out_group=None, flags=None, match=None, instructions=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if cookie_mask != None:
+            self.cookie_mask = cookie_mask
+        else:
+            self.cookie_mask = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if out_group != None:
+            self.out_group = out_group
+        else:
+            self.out_group = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if instructions != None:
+            self.instructions = instructions
+        else:
+            self.instructions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.cookie_mask))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append(util.pack_fm_cmd(self._command))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!L", self.out_group))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 2)
+        packed.append(self.match.pack())
+        packed.append(loxi.generic_util.pack_list(self.instructions))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_add()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 14)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.cookie = reader.read("!Q")[0]
+        obj.cookie_mask = reader.read("!Q")[0]
+        obj.table_id = reader.read("!B")[0]
+        __command = util.unpack_fm_cmd(reader)
+        assert(__command == 0)
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.out_port = util.unpack_port_no(reader)
+        obj.out_group = reader.read("!L")[0]
+        obj.flags = reader.read("!H")[0]
+        reader.skip(2)
+        obj.match = ofp.match.unpack(reader)
+        obj.instructions = loxi.generic_util.unpack_list(reader, ofp.instruction.instruction.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.cookie != other.cookie: return False
+        if self.cookie_mask != other.cookie_mask: return False
+        if self.table_id != other.table_id: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.priority != other.priority: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.out_port != other.out_port: return False
+        if self.out_group != other.out_group: return False
+        if self.flags != other.flags: return False
+        if self.match != other.match: return False
+        if self.instructions != other.instructions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_add {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("cookie_mask = ");
+                q.text("%#x" % self.cookie_mask)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("out_group = ");
+                q.text("%#x" % self.out_group)
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("instructions = ");
+                q.pp(self.instructions)
+            q.breakable()
+        q.text('}')
+
+flow_mod.subtypes[0] = flow_add
+
+class flow_delete(flow_mod):
+    version = 3
+    type = 14
+    _command = 3
+
+    def __init__(self, xid=None, cookie=None, cookie_mask=None, table_id=None, idle_timeout=None, hard_timeout=None, priority=None, buffer_id=None, out_port=None, out_group=None, flags=None, match=None, instructions=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if cookie_mask != None:
+            self.cookie_mask = cookie_mask
+        else:
+            self.cookie_mask = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if out_group != None:
+            self.out_group = out_group
+        else:
+            self.out_group = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if instructions != None:
+            self.instructions = instructions
+        else:
+            self.instructions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.cookie_mask))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append(util.pack_fm_cmd(self._command))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!L", self.out_group))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 2)
+        packed.append(self.match.pack())
+        packed.append(loxi.generic_util.pack_list(self.instructions))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_delete()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 14)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.cookie = reader.read("!Q")[0]
+        obj.cookie_mask = reader.read("!Q")[0]
+        obj.table_id = reader.read("!B")[0]
+        __command = util.unpack_fm_cmd(reader)
+        assert(__command == 3)
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.out_port = util.unpack_port_no(reader)
+        obj.out_group = reader.read("!L")[0]
+        obj.flags = reader.read("!H")[0]
+        reader.skip(2)
+        obj.match = ofp.match.unpack(reader)
+        obj.instructions = loxi.generic_util.unpack_list(reader, ofp.instruction.instruction.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.cookie != other.cookie: return False
+        if self.cookie_mask != other.cookie_mask: return False
+        if self.table_id != other.table_id: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.priority != other.priority: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.out_port != other.out_port: return False
+        if self.out_group != other.out_group: return False
+        if self.flags != other.flags: return False
+        if self.match != other.match: return False
+        if self.instructions != other.instructions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_delete {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("cookie_mask = ");
+                q.text("%#x" % self.cookie_mask)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("out_group = ");
+                q.text("%#x" % self.out_group)
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("instructions = ");
+                q.pp(self.instructions)
+            q.breakable()
+        q.text('}')
+
+flow_mod.subtypes[3] = flow_delete
+
+class flow_delete_strict(flow_mod):
+    version = 3
+    type = 14
+    _command = 4
+
+    def __init__(self, xid=None, cookie=None, cookie_mask=None, table_id=None, idle_timeout=None, hard_timeout=None, priority=None, buffer_id=None, out_port=None, out_group=None, flags=None, match=None, instructions=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if cookie_mask != None:
+            self.cookie_mask = cookie_mask
+        else:
+            self.cookie_mask = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if out_group != None:
+            self.out_group = out_group
+        else:
+            self.out_group = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if instructions != None:
+            self.instructions = instructions
+        else:
+            self.instructions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.cookie_mask))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append(util.pack_fm_cmd(self._command))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!L", self.out_group))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 2)
+        packed.append(self.match.pack())
+        packed.append(loxi.generic_util.pack_list(self.instructions))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_delete_strict()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 14)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.cookie = reader.read("!Q")[0]
+        obj.cookie_mask = reader.read("!Q")[0]
+        obj.table_id = reader.read("!B")[0]
+        __command = util.unpack_fm_cmd(reader)
+        assert(__command == 4)
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.out_port = util.unpack_port_no(reader)
+        obj.out_group = reader.read("!L")[0]
+        obj.flags = reader.read("!H")[0]
+        reader.skip(2)
+        obj.match = ofp.match.unpack(reader)
+        obj.instructions = loxi.generic_util.unpack_list(reader, ofp.instruction.instruction.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.cookie != other.cookie: return False
+        if self.cookie_mask != other.cookie_mask: return False
+        if self.table_id != other.table_id: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.priority != other.priority: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.out_port != other.out_port: return False
+        if self.out_group != other.out_group: return False
+        if self.flags != other.flags: return False
+        if self.match != other.match: return False
+        if self.instructions != other.instructions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_delete_strict {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("cookie_mask = ");
+                q.text("%#x" % self.cookie_mask)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("out_group = ");
+                q.text("%#x" % self.out_group)
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("instructions = ");
+                q.pp(self.instructions)
+            q.breakable()
+        q.text('}')
+
+flow_mod.subtypes[4] = flow_delete_strict
+
+class flow_mod_failed_error_msg(error_msg):
+    version = 3
+    type = 1
+    err_type = 5
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_mod_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 5)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_mod_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[5] = flow_mod_failed_error_msg
+
+class flow_modify(flow_mod):
+    version = 3
+    type = 14
+    _command = 1
+
+    def __init__(self, xid=None, cookie=None, cookie_mask=None, table_id=None, idle_timeout=None, hard_timeout=None, priority=None, buffer_id=None, out_port=None, out_group=None, flags=None, match=None, instructions=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if cookie_mask != None:
+            self.cookie_mask = cookie_mask
+        else:
+            self.cookie_mask = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if out_group != None:
+            self.out_group = out_group
+        else:
+            self.out_group = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if instructions != None:
+            self.instructions = instructions
+        else:
+            self.instructions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.cookie_mask))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append(util.pack_fm_cmd(self._command))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!L", self.out_group))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 2)
+        packed.append(self.match.pack())
+        packed.append(loxi.generic_util.pack_list(self.instructions))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_modify()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 14)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.cookie = reader.read("!Q")[0]
+        obj.cookie_mask = reader.read("!Q")[0]
+        obj.table_id = reader.read("!B")[0]
+        __command = util.unpack_fm_cmd(reader)
+        assert(__command == 1)
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.out_port = util.unpack_port_no(reader)
+        obj.out_group = reader.read("!L")[0]
+        obj.flags = reader.read("!H")[0]
+        reader.skip(2)
+        obj.match = ofp.match.unpack(reader)
+        obj.instructions = loxi.generic_util.unpack_list(reader, ofp.instruction.instruction.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.cookie != other.cookie: return False
+        if self.cookie_mask != other.cookie_mask: return False
+        if self.table_id != other.table_id: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.priority != other.priority: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.out_port != other.out_port: return False
+        if self.out_group != other.out_group: return False
+        if self.flags != other.flags: return False
+        if self.match != other.match: return False
+        if self.instructions != other.instructions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_modify {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("cookie_mask = ");
+                q.text("%#x" % self.cookie_mask)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("out_group = ");
+                q.text("%#x" % self.out_group)
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("instructions = ");
+                q.pp(self.instructions)
+            q.breakable()
+        q.text('}')
+
+flow_mod.subtypes[1] = flow_modify
+
+class flow_modify_strict(flow_mod):
+    version = 3
+    type = 14
+    _command = 2
+
+    def __init__(self, xid=None, cookie=None, cookie_mask=None, table_id=None, idle_timeout=None, hard_timeout=None, priority=None, buffer_id=None, out_port=None, out_group=None, flags=None, match=None, instructions=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if cookie_mask != None:
+            self.cookie_mask = cookie_mask
+        else:
+            self.cookie_mask = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if out_group != None:
+            self.out_group = out_group
+        else:
+            self.out_group = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if instructions != None:
+            self.instructions = instructions
+        else:
+            self.instructions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.cookie_mask))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append(util.pack_fm_cmd(self._command))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!L", self.out_group))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 2)
+        packed.append(self.match.pack())
+        packed.append(loxi.generic_util.pack_list(self.instructions))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_modify_strict()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 14)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.cookie = reader.read("!Q")[0]
+        obj.cookie_mask = reader.read("!Q")[0]
+        obj.table_id = reader.read("!B")[0]
+        __command = util.unpack_fm_cmd(reader)
+        assert(__command == 2)
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.out_port = util.unpack_port_no(reader)
+        obj.out_group = reader.read("!L")[0]
+        obj.flags = reader.read("!H")[0]
+        reader.skip(2)
+        obj.match = ofp.match.unpack(reader)
+        obj.instructions = loxi.generic_util.unpack_list(reader, ofp.instruction.instruction.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.cookie != other.cookie: return False
+        if self.cookie_mask != other.cookie_mask: return False
+        if self.table_id != other.table_id: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.priority != other.priority: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.out_port != other.out_port: return False
+        if self.out_group != other.out_group: return False
+        if self.flags != other.flags: return False
+        if self.match != other.match: return False
+        if self.instructions != other.instructions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_modify_strict {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("cookie_mask = ");
+                q.text("%#x" % self.cookie_mask)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("out_group = ");
+                q.text("%#x" % self.out_group)
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("instructions = ");
+                q.pp(self.instructions)
+            q.breakable()
+        q.text('}')
+
+flow_mod.subtypes[2] = flow_modify_strict
+
+class flow_removed(message):
+    version = 3
+    type = 11
+
+    def __init__(self, xid=None, cookie=None, priority=None, reason=None, table_id=None, duration_sec=None, duration_nsec=None, idle_timeout=None, hard_timeout=None, packet_count=None, byte_count=None, match=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if reason != None:
+            self.reason = reason
+        else:
+            self.reason = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if duration_sec != None:
+            self.duration_sec = duration_sec
+        else:
+            self.duration_sec = 0
+        if duration_nsec != None:
+            self.duration_nsec = duration_nsec
+        else:
+            self.duration_nsec = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if packet_count != None:
+            self.packet_count = packet_count
+        else:
+            self.packet_count = 0
+        if byte_count != None:
+            self.byte_count = byte_count
+        else:
+            self.byte_count = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!B", self.reason))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append(struct.pack("!L", self.duration_sec))
+        packed.append(struct.pack("!L", self.duration_nsec))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!Q", self.packet_count))
+        packed.append(struct.pack("!Q", self.byte_count))
+        packed.append(self.match.pack())
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_removed()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 11)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.cookie = reader.read("!Q")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.reason = reader.read("!B")[0]
+        obj.table_id = reader.read("!B")[0]
+        obj.duration_sec = reader.read("!L")[0]
+        obj.duration_nsec = reader.read("!L")[0]
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.packet_count = reader.read("!Q")[0]
+        obj.byte_count = reader.read("!Q")[0]
+        obj.match = ofp.match.unpack(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.cookie != other.cookie: return False
+        if self.priority != other.priority: return False
+        if self.reason != other.reason: return False
+        if self.table_id != other.table_id: return False
+        if self.duration_sec != other.duration_sec: return False
+        if self.duration_nsec != other.duration_nsec: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.packet_count != other.packet_count: return False
+        if self.byte_count != other.byte_count: return False
+        if self.match != other.match: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_removed {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("reason = ");
+                q.text("%#x" % self.reason)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("duration_sec = ");
+                q.text("%#x" % self.duration_sec)
+                q.text(","); q.breakable()
+                q.text("duration_nsec = ");
+                q.text("%#x" % self.duration_nsec)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("packet_count = ");
+                q.text("%#x" % self.packet_count)
+                q.text(","); q.breakable()
+                q.text("byte_count = ");
+                q.text("%#x" % self.byte_count)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[11] = flow_removed
+
+class flow_stats_reply(stats_reply):
+    version = 3
+    type = 19
+    stats_type = 1
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 1)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.flow_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[1] = flow_stats_reply
+
+class flow_stats_request(stats_request):
+    version = 3
+    type = 18
+    stats_type = 1
+
+    def __init__(self, xid=None, flags=None, table_id=None, out_port=None, out_group=None, cookie=None, cookie_mask=None, match=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if out_group != None:
+            self.out_group = out_group
+        else:
+            self.out_group = 0
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if cookie_mask != None:
+            self.cookie_mask = cookie_mask
+        else:
+            self.cookie_mask = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append('\x00' * 3)
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!L", self.out_group))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.cookie_mask))
+        packed.append(self.match.pack())
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 1)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.table_id = reader.read("!B")[0]
+        reader.skip(3)
+        obj.out_port = util.unpack_port_no(reader)
+        obj.out_group = reader.read("!L")[0]
+        reader.skip(4)
+        obj.cookie = reader.read("!Q")[0]
+        obj.cookie_mask = reader.read("!Q")[0]
+        obj.match = ofp.match.unpack(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.table_id != other.table_id: return False
+        if self.out_port != other.out_port: return False
+        if self.out_group != other.out_group: return False
+        if self.cookie != other.cookie: return False
+        if self.cookie_mask != other.cookie_mask: return False
+        if self.match != other.match: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("out_group = ");
+                q.text("%#x" % self.out_group)
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("cookie_mask = ");
+                q.text("%#x" % self.cookie_mask)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[1] = flow_stats_request
+
+class get_config_reply(message):
+    version = 3
+    type = 8
+
+    def __init__(self, xid=None, flags=None, miss_send_len=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if miss_send_len != None:
+            self.miss_send_len = miss_send_len
+        else:
+            self.miss_send_len = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(struct.pack("!H", self.miss_send_len))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = get_config_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 8)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.flags = reader.read("!H")[0]
+        obj.miss_send_len = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.miss_send_len != other.miss_send_len: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("get_config_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("miss_send_len = ");
+                q.text("%#x" % self.miss_send_len)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[8] = get_config_reply
+
+class get_config_request(message):
+    version = 3
+    type = 7
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = get_config_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 7)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("get_config_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+message.subtypes[7] = get_config_request
+
+class group_mod(message):
+    subtypes = {}
+
+    version = 3
+    type = 15
+
+    def __init__(self, xid=None, command=None, group_type=None, group_id=None, buckets=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if command != None:
+            self.command = command
+        else:
+            self.command = 0
+        if group_type != None:
+            self.group_type = group_type
+        else:
+            self.group_type = 0
+        if group_id != None:
+            self.group_id = group_id
+        else:
+            self.group_id = 0
+        if buckets != None:
+            self.buckets = buckets
+        else:
+            self.buckets = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.command))
+        packed.append(struct.pack("!B", self.group_type))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!L", self.group_id))
+        packed.append(loxi.generic_util.pack_list(self.buckets))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 8)
+        subclass = group_mod.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = group_mod()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 15)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.command = reader.read("!H")[0]
+        obj.group_type = reader.read("!B")[0]
+        reader.skip(1)
+        obj.group_id = reader.read("!L")[0]
+        obj.buckets = loxi.generic_util.unpack_list(reader, ofp.common.bucket.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.command != other.command: return False
+        if self.group_type != other.group_type: return False
+        if self.group_id != other.group_id: return False
+        if self.buckets != other.buckets: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_mod {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("group_type = ");
+                q.text("%#x" % self.group_type)
+                q.text(","); q.breakable()
+                q.text("group_id = ");
+                q.text("%#x" % self.group_id)
+                q.text(","); q.breakable()
+                q.text("buckets = ");
+                q.pp(self.buckets)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[15] = group_mod
+
+class group_add(group_mod):
+    version = 3
+    type = 15
+    command = 0
+
+    def __init__(self, xid=None, group_type=None, group_id=None, buckets=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if group_type != None:
+            self.group_type = group_type
+        else:
+            self.group_type = 0
+        if group_id != None:
+            self.group_id = group_id
+        else:
+            self.group_id = 0
+        if buckets != None:
+            self.buckets = buckets
+        else:
+            self.buckets = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.command))
+        packed.append(struct.pack("!B", self.group_type))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!L", self.group_id))
+        packed.append(loxi.generic_util.pack_list(self.buckets))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_add()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 15)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _command = reader.read("!H")[0]
+        assert(_command == 0)
+        obj.group_type = reader.read("!B")[0]
+        reader.skip(1)
+        obj.group_id = reader.read("!L")[0]
+        obj.buckets = loxi.generic_util.unpack_list(reader, ofp.common.bucket.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.group_type != other.group_type: return False
+        if self.group_id != other.group_id: return False
+        if self.buckets != other.buckets: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_add {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("group_type = ");
+                q.text("%#x" % self.group_type)
+                q.text(","); q.breakable()
+                q.text("group_id = ");
+                q.text("%#x" % self.group_id)
+                q.text(","); q.breakable()
+                q.text("buckets = ");
+                q.pp(self.buckets)
+            q.breakable()
+        q.text('}')
+
+group_mod.subtypes[0] = group_add
+
+class group_delete(group_mod):
+    version = 3
+    type = 15
+    command = 2
+
+    def __init__(self, xid=None, group_type=None, group_id=None, buckets=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if group_type != None:
+            self.group_type = group_type
+        else:
+            self.group_type = 0
+        if group_id != None:
+            self.group_id = group_id
+        else:
+            self.group_id = 0
+        if buckets != None:
+            self.buckets = buckets
+        else:
+            self.buckets = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.command))
+        packed.append(struct.pack("!B", self.group_type))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!L", self.group_id))
+        packed.append(loxi.generic_util.pack_list(self.buckets))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_delete()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 15)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _command = reader.read("!H")[0]
+        assert(_command == 2)
+        obj.group_type = reader.read("!B")[0]
+        reader.skip(1)
+        obj.group_id = reader.read("!L")[0]
+        obj.buckets = loxi.generic_util.unpack_list(reader, ofp.common.bucket.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.group_type != other.group_type: return False
+        if self.group_id != other.group_id: return False
+        if self.buckets != other.buckets: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_delete {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("group_type = ");
+                q.text("%#x" % self.group_type)
+                q.text(","); q.breakable()
+                q.text("group_id = ");
+                q.text("%#x" % self.group_id)
+                q.text(","); q.breakable()
+                q.text("buckets = ");
+                q.pp(self.buckets)
+            q.breakable()
+        q.text('}')
+
+group_mod.subtypes[2] = group_delete
+
+class group_desc_stats_reply(stats_reply):
+    version = 3
+    type = 19
+    stats_type = 7
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_desc_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 7)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.group_desc_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_desc_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[7] = group_desc_stats_reply
+
+class group_desc_stats_request(stats_request):
+    version = 3
+    type = 18
+    stats_type = 7
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_desc_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 7)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_desc_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[7] = group_desc_stats_request
+
+class group_features_stats_reply(stats_reply):
+    version = 3
+    type = 19
+    stats_type = 8
+
+    def __init__(self, xid=None, flags=None, types=None, capabilities=None, max_groups_all=None, max_groups_select=None, max_groups_indirect=None, max_groups_ff=None, actions_all=None, actions_select=None, actions_indirect=None, actions_ff=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if types != None:
+            self.types = types
+        else:
+            self.types = 0
+        if capabilities != None:
+            self.capabilities = capabilities
+        else:
+            self.capabilities = 0
+        if max_groups_all != None:
+            self.max_groups_all = max_groups_all
+        else:
+            self.max_groups_all = 0
+        if max_groups_select != None:
+            self.max_groups_select = max_groups_select
+        else:
+            self.max_groups_select = 0
+        if max_groups_indirect != None:
+            self.max_groups_indirect = max_groups_indirect
+        else:
+            self.max_groups_indirect = 0
+        if max_groups_ff != None:
+            self.max_groups_ff = max_groups_ff
+        else:
+            self.max_groups_ff = 0
+        if actions_all != None:
+            self.actions_all = actions_all
+        else:
+            self.actions_all = 0
+        if actions_select != None:
+            self.actions_select = actions_select
+        else:
+            self.actions_select = 0
+        if actions_indirect != None:
+            self.actions_indirect = actions_indirect
+        else:
+            self.actions_indirect = 0
+        if actions_ff != None:
+            self.actions_ff = actions_ff
+        else:
+            self.actions_ff = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.types))
+        packed.append(struct.pack("!L", self.capabilities))
+        packed.append(struct.pack("!L", self.max_groups_all))
+        packed.append(struct.pack("!L", self.max_groups_select))
+        packed.append(struct.pack("!L", self.max_groups_indirect))
+        packed.append(struct.pack("!L", self.max_groups_ff))
+        packed.append(struct.pack("!L", self.actions_all))
+        packed.append(struct.pack("!L", self.actions_select))
+        packed.append(struct.pack("!L", self.actions_indirect))
+        packed.append(struct.pack("!L", self.actions_ff))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_features_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 8)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.types = reader.read("!L")[0]
+        obj.capabilities = reader.read("!L")[0]
+        obj.max_groups_all = reader.read("!L")[0]
+        obj.max_groups_select = reader.read("!L")[0]
+        obj.max_groups_indirect = reader.read("!L")[0]
+        obj.max_groups_ff = reader.read("!L")[0]
+        obj.actions_all = reader.read("!L")[0]
+        obj.actions_select = reader.read("!L")[0]
+        obj.actions_indirect = reader.read("!L")[0]
+        obj.actions_ff = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.types != other.types: return False
+        if self.capabilities != other.capabilities: return False
+        if self.max_groups_all != other.max_groups_all: return False
+        if self.max_groups_select != other.max_groups_select: return False
+        if self.max_groups_indirect != other.max_groups_indirect: return False
+        if self.max_groups_ff != other.max_groups_ff: return False
+        if self.actions_all != other.actions_all: return False
+        if self.actions_select != other.actions_select: return False
+        if self.actions_indirect != other.actions_indirect: return False
+        if self.actions_ff != other.actions_ff: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_features_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("types = ");
+                q.text("%#x" % self.types)
+                q.text(","); q.breakable()
+                q.text("capabilities = ");
+                q.text("%#x" % self.capabilities)
+                q.text(","); q.breakable()
+                q.text("max_groups_all = ");
+                q.text("%#x" % self.max_groups_all)
+                q.text(","); q.breakable()
+                q.text("max_groups_select = ");
+                q.text("%#x" % self.max_groups_select)
+                q.text(","); q.breakable()
+                q.text("max_groups_indirect = ");
+                q.text("%#x" % self.max_groups_indirect)
+                q.text(","); q.breakable()
+                q.text("max_groups_ff = ");
+                q.text("%#x" % self.max_groups_ff)
+                q.text(","); q.breakable()
+                q.text("actions_all = ");
+                q.text("%#x" % self.actions_all)
+                q.text(","); q.breakable()
+                q.text("actions_select = ");
+                q.text("%#x" % self.actions_select)
+                q.text(","); q.breakable()
+                q.text("actions_indirect = ");
+                q.text("%#x" % self.actions_indirect)
+                q.text(","); q.breakable()
+                q.text("actions_ff = ");
+                q.text("%#x" % self.actions_ff)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[8] = group_features_stats_reply
+
+class group_features_stats_request(stats_request):
+    version = 3
+    type = 18
+    stats_type = 8
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_features_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 8)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_features_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[8] = group_features_stats_request
+
+class group_mod_failed_error_msg(error_msg):
+    version = 3
+    type = 1
+    err_type = 6
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_mod_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 6)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_mod_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[6] = group_mod_failed_error_msg
+
+class group_modify(group_mod):
+    version = 3
+    type = 15
+    command = 1
+
+    def __init__(self, xid=None, group_type=None, group_id=None, buckets=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if group_type != None:
+            self.group_type = group_type
+        else:
+            self.group_type = 0
+        if group_id != None:
+            self.group_id = group_id
+        else:
+            self.group_id = 0
+        if buckets != None:
+            self.buckets = buckets
+        else:
+            self.buckets = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.command))
+        packed.append(struct.pack("!B", self.group_type))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!L", self.group_id))
+        packed.append(loxi.generic_util.pack_list(self.buckets))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_modify()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 15)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _command = reader.read("!H")[0]
+        assert(_command == 1)
+        obj.group_type = reader.read("!B")[0]
+        reader.skip(1)
+        obj.group_id = reader.read("!L")[0]
+        obj.buckets = loxi.generic_util.unpack_list(reader, ofp.common.bucket.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.group_type != other.group_type: return False
+        if self.group_id != other.group_id: return False
+        if self.buckets != other.buckets: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_modify {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("group_type = ");
+                q.text("%#x" % self.group_type)
+                q.text(","); q.breakable()
+                q.text("group_id = ");
+                q.text("%#x" % self.group_id)
+                q.text(","); q.breakable()
+                q.text("buckets = ");
+                q.pp(self.buckets)
+            q.breakable()
+        q.text('}')
+
+group_mod.subtypes[1] = group_modify
+
+class group_stats_reply(stats_reply):
+    version = 3
+    type = 19
+    stats_type = 6
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 6)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.group_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[6] = group_stats_reply
+
+class group_stats_request(stats_request):
+    version = 3
+    type = 18
+    stats_type = 6
+
+    def __init__(self, xid=None, flags=None, group_id=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if group_id != None:
+            self.group_id = group_id
+        else:
+            self.group_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.group_id))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 6)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.group_id = reader.read("!L")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.group_id != other.group_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("group_id = ");
+                q.text("%#x" % self.group_id)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[6] = group_stats_request
+
+class hello(message):
+    version = 3
+    type = 0
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = hello()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 0)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("hello {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+message.subtypes[0] = hello
+
+class hello_failed_error_msg(error_msg):
+    version = 3
+    type = 1
+    err_type = 0
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = hello_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 0)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("hello_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[0] = hello_failed_error_msg
+
+class nicira_header(experimenter):
+    subtypes = {}
+
+    version = 3
+    type = 4
+    experimenter = 8992
+
+    def __init__(self, xid=None, subtype=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 12)
+        subclass = nicira_header.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = nicira_header()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 8992)
+        obj.subtype = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("nicira_header {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+experimenter.subtypes[8992] = nicira_header
+
+class packet_in(message):
+    version = 3
+    type = 10
+
+    def __init__(self, xid=None, buffer_id=None, total_len=None, reason=None, table_id=None, match=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if total_len != None:
+            self.total_len = total_len
+        else:
+            self.total_len = 0
+        if reason != None:
+            self.reason = reason
+        else:
+            self.reason = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(struct.pack("!H", self.total_len))
+        packed.append(struct.pack("!B", self.reason))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append(self.match.pack())
+        packed.append('\x00' * 2)
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = packet_in()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 10)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.total_len = reader.read("!H")[0]
+        obj.reason = reader.read("!B")[0]
+        obj.table_id = reader.read("!B")[0]
+        obj.match = ofp.match.unpack(reader)
+        reader.skip(2)
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.total_len != other.total_len: return False
+        if self.reason != other.reason: return False
+        if self.table_id != other.table_id: return False
+        if self.match != other.match: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("packet_in {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("total_len = ");
+                q.text("%#x" % self.total_len)
+                q.text(","); q.breakable()
+                q.text("reason = ");
+                q.text("%#x" % self.reason)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[10] = packet_in
+
+class packet_out(message):
+    version = 3
+    type = 13
+
+    def __init__(self, xid=None, buffer_id=None, in_port=None, actions=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if in_port != None:
+            self.in_port = in_port
+        else:
+            self.in_port = 0
+        if actions != None:
+            self.actions = actions
+        else:
+            self.actions = []
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(util.pack_port_no(self.in_port))
+        packed.append(struct.pack("!H", 0)) # placeholder for actions_len at index 6
+        packed.append('\x00' * 6)
+        packed.append(loxi.generic_util.pack_list(self.actions))
+        packed[6] = struct.pack("!H", len(packed[-1]))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = packet_out()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 13)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.in_port = util.unpack_port_no(reader)
+        _actions_len = reader.read("!H")[0]
+        reader.skip(6)
+        obj.actions = loxi.generic_util.unpack_list(reader.slice(_actions_len), ofp.action.action.unpack)
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.in_port != other.in_port: return False
+        if self.actions != other.actions: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("packet_out {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("in_port = ");
+                q.text(util.pretty_port(self.in_port))
+                q.text(","); q.breakable()
+                q.text("actions = ");
+                q.pp(self.actions)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[13] = packet_out
+
+class port_mod(message):
+    version = 3
+    type = 16
+
+    def __init__(self, xid=None, port_no=None, hw_addr=None, config=None, mask=None, advertise=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if hw_addr != None:
+            self.hw_addr = hw_addr
+        else:
+            self.hw_addr = [0,0,0,0,0,0]
+        if config != None:
+            self.config = config
+        else:
+            self.config = 0
+        if mask != None:
+            self.mask = mask
+        else:
+            self.mask = 0
+        if advertise != None:
+            self.advertise = advertise
+        else:
+            self.advertise = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!6B", *self.hw_addr))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!L", self.config))
+        packed.append(struct.pack("!L", self.mask))
+        packed.append(struct.pack("!L", self.advertise))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_mod()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 16)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.port_no = util.unpack_port_no(reader)
+        reader.skip(4)
+        obj.hw_addr = list(reader.read('!6B'))
+        reader.skip(2)
+        obj.config = reader.read("!L")[0]
+        obj.mask = reader.read("!L")[0]
+        obj.advertise = reader.read("!L")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.port_no != other.port_no: return False
+        if self.hw_addr != other.hw_addr: return False
+        if self.config != other.config: return False
+        if self.mask != other.mask: return False
+        if self.advertise != other.advertise: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_mod {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("hw_addr = ");
+                q.text(util.pretty_mac(self.hw_addr))
+                q.text(","); q.breakable()
+                q.text("config = ");
+                q.text("%#x" % self.config)
+                q.text(","); q.breakable()
+                q.text("mask = ");
+                q.text("%#x" % self.mask)
+                q.text(","); q.breakable()
+                q.text("advertise = ");
+                q.text("%#x" % self.advertise)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[16] = port_mod
+
+class port_mod_failed_error_msg(error_msg):
+    version = 3
+    type = 1
+    err_type = 7
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_mod_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 7)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_mod_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[7] = port_mod_failed_error_msg
+
+class port_stats_reply(stats_reply):
+    version = 3
+    type = 19
+    stats_type = 4
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 4)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.port_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[4] = port_stats_reply
+
+class port_stats_request(stats_request):
+    version = 3
+    type = 18
+    stats_type = 4
+
+    def __init__(self, xid=None, flags=None, port_no=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 4)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.port_no = util.unpack_port_no(reader)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.port_no != other.port_no: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[4] = port_stats_request
+
+class port_status(message):
+    version = 3
+    type = 12
+
+    def __init__(self, xid=None, reason=None, desc=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if reason != None:
+            self.reason = reason
+        else:
+            self.reason = 0
+        if desc != None:
+            self.desc = desc
+        else:
+            self.desc = ofp.port_desc()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!B", self.reason))
+        packed.append('\x00' * 7)
+        packed.append(self.desc.pack())
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_status()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 12)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.reason = reader.read("!B")[0]
+        reader.skip(7)
+        obj.desc = ofp.port_desc.unpack(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.reason != other.reason: return False
+        if self.desc != other.desc: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_status {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("reason = ");
+                q.text("%#x" % self.reason)
+                q.text(","); q.breakable()
+                q.text("desc = ");
+                q.pp(self.desc)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[12] = port_status
+
+class queue_get_config_reply(message):
+    version = 3
+    type = 23
+
+    def __init__(self, xid=None, port=None, queues=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if port != None:
+            self.port = port
+        else:
+            self.port = 0
+        if queues != None:
+            self.queues = queues
+        else:
+            self.queues = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(util.pack_port_no(self.port))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.queues))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_get_config_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 23)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.port = util.unpack_port_no(reader)
+        reader.skip(4)
+        obj.queues = loxi.generic_util.unpack_list(reader, ofp.common.packet_queue.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.port != other.port: return False
+        if self.queues != other.queues: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_get_config_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("port = ");
+                q.text(util.pretty_port(self.port))
+                q.text(","); q.breakable()
+                q.text("queues = ");
+                q.pp(self.queues)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[23] = queue_get_config_reply
+
+class queue_get_config_request(message):
+    version = 3
+    type = 22
+
+    def __init__(self, xid=None, port=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if port != None:
+            self.port = port
+        else:
+            self.port = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(util.pack_port_no(self.port))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_get_config_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 22)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.port = util.unpack_port_no(reader)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.port != other.port: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_get_config_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("port = ");
+                q.text(util.pretty_port(self.port))
+            q.breakable()
+        q.text('}')
+
+message.subtypes[22] = queue_get_config_request
+
+class queue_op_failed_error_msg(error_msg):
+    version = 3
+    type = 1
+    err_type = 9
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_op_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 9)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_op_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[9] = queue_op_failed_error_msg
+
+class queue_stats_reply(stats_reply):
+    version = 3
+    type = 19
+    stats_type = 5
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 5)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.queue_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[5] = queue_stats_reply
+
+class queue_stats_request(stats_request):
+    version = 3
+    type = 18
+    stats_type = 5
+
+    def __init__(self, xid=None, flags=None, port_no=None, queue_id=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if queue_id != None:
+            self.queue_id = queue_id
+        else:
+            self.queue_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!L", self.queue_id))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 5)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.port_no = util.unpack_port_no(reader)
+        obj.queue_id = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.port_no != other.port_no: return False
+        if self.queue_id != other.queue_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("queue_id = ");
+                q.text("%#x" % self.queue_id)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[5] = queue_stats_request
+
+class role_reply(message):
+    version = 3
+    type = 25
+
+    def __init__(self, xid=None, role=None, generation_id=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if role != None:
+            self.role = role
+        else:
+            self.role = 0
+        if generation_id != None:
+            self.generation_id = generation_id
+        else:
+            self.generation_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.role))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!Q", self.generation_id))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = role_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 25)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.role = reader.read("!L")[0]
+        reader.skip(4)
+        obj.generation_id = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.role != other.role: return False
+        if self.generation_id != other.generation_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("role_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("role = ");
+                q.text("%#x" % self.role)
+                q.text(","); q.breakable()
+                q.text("generation_id = ");
+                q.text("%#x" % self.generation_id)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[25] = role_reply
+
+class role_request(message):
+    version = 3
+    type = 24
+
+    def __init__(self, xid=None, role=None, generation_id=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if role != None:
+            self.role = role
+        else:
+            self.role = 0
+        if generation_id != None:
+            self.generation_id = generation_id
+        else:
+            self.generation_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.role))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!Q", self.generation_id))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = role_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 24)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.role = reader.read("!L")[0]
+        reader.skip(4)
+        obj.generation_id = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.role != other.role: return False
+        if self.generation_id != other.generation_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("role_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("role = ");
+                q.text("%#x" % self.role)
+                q.text(","); q.breakable()
+                q.text("generation_id = ");
+                q.text("%#x" % self.generation_id)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[24] = role_request
+
+class role_request_failed_error_msg(error_msg):
+    version = 3
+    type = 1
+    err_type = 11
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = role_request_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 11)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("role_request_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[11] = role_request_failed_error_msg
+
+class set_config(message):
+    version = 3
+    type = 9
+
+    def __init__(self, xid=None, flags=None, miss_send_len=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if miss_send_len != None:
+            self.miss_send_len = miss_send_len
+        else:
+            self.miss_send_len = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(struct.pack("!H", self.miss_send_len))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_config()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 9)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.flags = reader.read("!H")[0]
+        obj.miss_send_len = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.miss_send_len != other.miss_send_len: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_config {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("miss_send_len = ");
+                q.text("%#x" % self.miss_send_len)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[9] = set_config
+
+class switch_config_failed_error_msg(error_msg):
+    version = 3
+    type = 1
+    err_type = 10
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = switch_config_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 10)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("switch_config_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[10] = switch_config_failed_error_msg
+
+class table_mod(message):
+    version = 3
+    type = 17
+
+    def __init__(self, xid=None, table_id=None, config=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if config != None:
+            self.config = config
+        else:
+            self.config = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append('\x00' * 3)
+        packed.append(struct.pack("!L", self.config))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_mod()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 17)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.table_id = reader.read("!B")[0]
+        reader.skip(3)
+        obj.config = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.table_id != other.table_id: return False
+        if self.config != other.config: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_mod {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("config = ");
+                q.text("%#x" % self.config)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[17] = table_mod
+
+class table_mod_failed_error_msg(error_msg):
+    version = 3
+    type = 1
+    err_type = 8
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_mod_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 8)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_mod_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[8] = table_mod_failed_error_msg
+
+class table_stats_reply(stats_reply):
+    version = 3
+    type = 19
+    stats_type = 3
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 3)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.table_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[3] = table_stats_reply
+
+class table_stats_request(stats_request):
+    version = 3
+    type = 18
+    stats_type = 3
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 3)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 3)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[3] = table_stats_request
+
+
+def parse_header(buf):
+    if len(buf) < 8:
+        raise loxi.ProtocolError("too short to be an OpenFlow message")
+    return struct.unpack_from("!BBHL", buf)
+
+def parse_message(buf):
+    msg_ver, msg_type, msg_len, msg_xid = parse_header(buf)
+    if msg_ver != ofp.OFP_VERSION and msg_type != ofp.OFPT_HELLO:
+        raise loxi.ProtocolError("wrong OpenFlow version (expected %d, got %d)" % (ofp.OFP_VERSION, msg_ver))
+    if len(buf) != msg_len:
+        raise loxi.ProtocolError("incorrect message size")
+    return message.unpack(loxi.generic_util.OFReader(buf))
diff --git a/Fabric/Utilities/src/python/loxi/of12/oxm.py b/Fabric/Utilities/src/python/loxi/of12/oxm.py
new file mode 100644
index 0000000..85accd4
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of12/oxm.py
@@ -0,0 +1,5502 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of12']
+
+class oxm(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type_len=None):
+        if type_len != None:
+            self.type_len = type_len
+        else:
+            self.type_len = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 0)
+        subclass = oxm.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = oxm()
+        obj.type_len = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type_len != other.type_len: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("oxm {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class arp_op(oxm):
+    type_len = 2147494402
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = arp_op()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147494402)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("arp_op {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147494402] = arp_op
+
+class arp_op_masked(oxm):
+    type_len = 2147494660
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        packed.append(struct.pack("!H", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = arp_op_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147494660)
+        obj.value = reader.read("!H")[0]
+        obj.value_mask = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("arp_op_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147494660] = arp_op_masked
+
+class arp_sha(oxm):
+    type_len = 2147495942
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = arp_sha()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147495942)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("arp_sha {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147495942] = arp_sha
+
+class arp_sha_masked(oxm):
+    type_len = 2147496204
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        packed.append(struct.pack("!6B", *self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = arp_sha_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147496204)
+        obj.value = list(reader.read('!6B'))
+        obj.value_mask = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("arp_sha_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_mac(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147496204] = arp_sha_masked
+
+class arp_spa(oxm):
+    type_len = 2147494916
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = arp_spa()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147494916)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("arp_spa {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147494916] = arp_spa
+
+class arp_spa_masked(oxm):
+    type_len = 2147495176
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = arp_spa_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147495176)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("arp_spa_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147495176] = arp_spa_masked
+
+class arp_tha(oxm):
+    type_len = 2147496454
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = arp_tha()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147496454)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("arp_tha {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147496454] = arp_tha
+
+class arp_tha_masked(oxm):
+    type_len = 2147496716
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        packed.append(struct.pack("!6B", *self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = arp_tha_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147496716)
+        obj.value = list(reader.read('!6B'))
+        obj.value_mask = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("arp_tha_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_mac(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147496716] = arp_tha_masked
+
+class arp_tpa(oxm):
+    type_len = 2147495428
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = arp_tpa()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147495428)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("arp_tpa {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147495428] = arp_tpa
+
+class arp_tpa_masked(oxm):
+    type_len = 2147495688
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = arp_tpa_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147495688)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("arp_tpa_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147495688] = arp_tpa_masked
+
+class bsn_egr_port_group_id(oxm):
+    type_len = 200196
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_egr_port_group_id()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 200196)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_egr_port_group_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[200196] = bsn_egr_port_group_id
+
+class bsn_egr_port_group_id_masked(oxm):
+    type_len = 200456
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_egr_port_group_id_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 200456)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_egr_port_group_id_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[200456] = bsn_egr_port_group_id_masked
+
+class bsn_global_vrf_allowed(oxm):
+    type_len = 198145
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_global_vrf_allowed()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 198145)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_global_vrf_allowed {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[198145] = bsn_global_vrf_allowed
+
+class bsn_global_vrf_allowed_masked(oxm):
+    type_len = 198402
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        packed.append(struct.pack("!B", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_global_vrf_allowed_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 198402)
+        obj.value = reader.read("!B")[0]
+        obj.value_mask = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_global_vrf_allowed_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[198402] = bsn_global_vrf_allowed_masked
+
+class bsn_in_ports_128(oxm):
+    type_len = 196624
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = set()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(util.pack_bitmap_128(self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_in_ports_128()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 196624)
+        obj.value = util.unpack_bitmap_128(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_in_ports_128 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[196624] = bsn_in_ports_128
+
+class bsn_in_ports_128_masked(oxm):
+    type_len = 196896
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = set()
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = set()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(util.pack_bitmap_128(self.value))
+        packed.append(util.pack_bitmap_128(self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_in_ports_128_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 196896)
+        obj.value = util.unpack_bitmap_128(reader)
+        obj.value_mask = util.unpack_bitmap_128(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_in_ports_128_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.pp(self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[196896] = bsn_in_ports_128_masked
+
+class bsn_in_ports_512(oxm):
+    type_len = 206400
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = set()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(util.pack_bitmap_512(self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_in_ports_512()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 206400)
+        obj.value = util.unpack_bitmap_512(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_in_ports_512 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[206400] = bsn_in_ports_512
+
+class bsn_in_ports_512_masked(oxm):
+    type_len = 206720
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = set()
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = set()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(util.pack_bitmap_512(self.value))
+        packed.append(util.pack_bitmap_512(self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_in_ports_512_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 206720)
+        obj.value = util.unpack_bitmap_512(reader)
+        obj.value_mask = util.unpack_bitmap_512(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_in_ports_512_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.pp(self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[206720] = bsn_in_ports_512_masked
+
+class bsn_ingress_port_group_id(oxm):
+    type_len = 206852
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_ingress_port_group_id()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 206852)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_ingress_port_group_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[206852] = bsn_ingress_port_group_id
+
+class bsn_ingress_port_group_id_masked(oxm):
+    type_len = 207112
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_ingress_port_group_id_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 207112)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_ingress_port_group_id_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[207112] = bsn_ingress_port_group_id_masked
+
+class bsn_l2_cache_hit(oxm):
+    type_len = 205825
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_l2_cache_hit()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 205825)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_l2_cache_hit {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[205825] = bsn_l2_cache_hit
+
+class bsn_l2_cache_hit_masked(oxm):
+    type_len = 206082
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        packed.append(struct.pack("!B", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_l2_cache_hit_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 206082)
+        obj.value = reader.read("!B")[0]
+        obj.value_mask = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_l2_cache_hit_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[206082] = bsn_l2_cache_hit_masked
+
+class bsn_l3_dst_class_id(oxm):
+    type_len = 199684
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_l3_dst_class_id()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 199684)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_l3_dst_class_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[199684] = bsn_l3_dst_class_id
+
+class bsn_l3_dst_class_id_masked(oxm):
+    type_len = 199944
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_l3_dst_class_id_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 199944)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_l3_dst_class_id_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[199944] = bsn_l3_dst_class_id_masked
+
+class bsn_l3_interface_class_id(oxm):
+    type_len = 198660
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_l3_interface_class_id()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 198660)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_l3_interface_class_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[198660] = bsn_l3_interface_class_id
+
+class bsn_l3_interface_class_id_masked(oxm):
+    type_len = 198920
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_l3_interface_class_id_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 198920)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_l3_interface_class_id_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[198920] = bsn_l3_interface_class_id_masked
+
+class bsn_l3_src_class_id(oxm):
+    type_len = 199172
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_l3_src_class_id()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 199172)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_l3_src_class_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[199172] = bsn_l3_src_class_id
+
+class bsn_l3_src_class_id_masked(oxm):
+    type_len = 199432
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_l3_src_class_id_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 199432)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_l3_src_class_id_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[199432] = bsn_l3_src_class_id_masked
+
+class bsn_lag_id(oxm):
+    type_len = 197124
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_lag_id()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 197124)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_lag_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[197124] = bsn_lag_id
+
+class bsn_lag_id_masked(oxm):
+    type_len = 197384
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_lag_id_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 197384)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_lag_id_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[197384] = bsn_lag_id_masked
+
+class bsn_tcp_flags(oxm):
+    type_len = 204802
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_tcp_flags()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 204802)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_tcp_flags {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[204802] = bsn_tcp_flags
+
+class bsn_tcp_flags_masked(oxm):
+    type_len = 205060
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        packed.append(struct.pack("!H", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_tcp_flags_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 205060)
+        obj.value = reader.read("!H")[0]
+        obj.value_mask = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_tcp_flags_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[205060] = bsn_tcp_flags_masked
+
+class bsn_udf0(oxm):
+    type_len = 200708
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf0()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 200708)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf0 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[200708] = bsn_udf0
+
+class bsn_udf0_masked(oxm):
+    type_len = 200968
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf0_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 200968)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf0_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[200968] = bsn_udf0_masked
+
+class bsn_udf1(oxm):
+    type_len = 201220
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf1()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 201220)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf1 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[201220] = bsn_udf1
+
+class bsn_udf1_masked(oxm):
+    type_len = 201480
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf1_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 201480)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf1_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[201480] = bsn_udf1_masked
+
+class bsn_udf2(oxm):
+    type_len = 201732
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf2()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 201732)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf2 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[201732] = bsn_udf2
+
+class bsn_udf2_masked(oxm):
+    type_len = 201992
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf2_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 201992)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf2_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[201992] = bsn_udf2_masked
+
+class bsn_udf3(oxm):
+    type_len = 202244
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf3()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 202244)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf3 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[202244] = bsn_udf3
+
+class bsn_udf3_masked(oxm):
+    type_len = 202504
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf3_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 202504)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf3_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[202504] = bsn_udf3_masked
+
+class bsn_udf4(oxm):
+    type_len = 202756
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf4()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 202756)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf4 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[202756] = bsn_udf4
+
+class bsn_udf4_masked(oxm):
+    type_len = 203016
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf4_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 203016)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf4_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[203016] = bsn_udf4_masked
+
+class bsn_udf5(oxm):
+    type_len = 203268
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf5()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 203268)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf5 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[203268] = bsn_udf5
+
+class bsn_udf5_masked(oxm):
+    type_len = 203528
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf5_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 203528)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf5_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[203528] = bsn_udf5_masked
+
+class bsn_udf6(oxm):
+    type_len = 203780
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf6()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 203780)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf6 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[203780] = bsn_udf6
+
+class bsn_udf6_masked(oxm):
+    type_len = 204040
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf6_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 204040)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf6_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[204040] = bsn_udf6_masked
+
+class bsn_udf7(oxm):
+    type_len = 204292
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf7()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 204292)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf7 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[204292] = bsn_udf7
+
+class bsn_udf7_masked(oxm):
+    type_len = 204552
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf7_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 204552)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf7_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[204552] = bsn_udf7_masked
+
+class bsn_vlan_xlate_port_group_id(oxm):
+    type_len = 205316
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vlan_xlate_port_group_id()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 205316)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vlan_xlate_port_group_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[205316] = bsn_vlan_xlate_port_group_id
+
+class bsn_vlan_xlate_port_group_id_masked(oxm):
+    type_len = 205576
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vlan_xlate_port_group_id_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 205576)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vlan_xlate_port_group_id_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[205576] = bsn_vlan_xlate_port_group_id_masked
+
+class bsn_vrf(oxm):
+    type_len = 197636
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vrf()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 197636)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vrf {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[197636] = bsn_vrf
+
+class bsn_vrf_masked(oxm):
+    type_len = 197896
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vrf_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 197896)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vrf_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[197896] = bsn_vrf_masked
+
+class eth_dst(oxm):
+    type_len = 2147485190
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = eth_dst()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147485190)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("eth_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147485190] = eth_dst
+
+class eth_dst_masked(oxm):
+    type_len = 2147485452
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        packed.append(struct.pack("!6B", *self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = eth_dst_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147485452)
+        obj.value = list(reader.read('!6B'))
+        obj.value_mask = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("eth_dst_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_mac(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147485452] = eth_dst_masked
+
+class eth_src(oxm):
+    type_len = 2147485702
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = eth_src()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147485702)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("eth_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147485702] = eth_src
+
+class eth_src_masked(oxm):
+    type_len = 2147485964
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        packed.append(struct.pack("!6B", *self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = eth_src_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147485964)
+        obj.value = list(reader.read('!6B'))
+        obj.value_mask = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("eth_src_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_mac(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147485964] = eth_src_masked
+
+class eth_type(oxm):
+    type_len = 2147486210
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = eth_type()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147486210)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("eth_type {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147486210] = eth_type
+
+class eth_type_masked(oxm):
+    type_len = 2147486468
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        packed.append(struct.pack("!H", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = eth_type_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147486468)
+        obj.value = reader.read("!H")[0]
+        obj.value_mask = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("eth_type_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147486468] = eth_type_masked
+
+class icmpv4_code(oxm):
+    type_len = 2147493889
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = icmpv4_code()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147493889)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("icmpv4_code {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147493889] = icmpv4_code
+
+class icmpv4_code_masked(oxm):
+    type_len = 2147494146
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        packed.append(struct.pack("!B", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = icmpv4_code_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147494146)
+        obj.value = reader.read("!B")[0]
+        obj.value_mask = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("icmpv4_code_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147494146] = icmpv4_code_masked
+
+class icmpv4_type(oxm):
+    type_len = 2147493377
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = icmpv4_type()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147493377)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("icmpv4_type {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147493377] = icmpv4_type
+
+class icmpv4_type_masked(oxm):
+    type_len = 2147493634
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        packed.append(struct.pack("!B", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = icmpv4_type_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147493634)
+        obj.value = reader.read("!B")[0]
+        obj.value_mask = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("icmpv4_type_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147493634] = icmpv4_type_masked
+
+class icmpv6_code(oxm):
+    type_len = 2147499009
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = icmpv6_code()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147499009)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("icmpv6_code {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147499009] = icmpv6_code
+
+class icmpv6_code_masked(oxm):
+    type_len = 2147499266
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        packed.append(struct.pack("!B", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = icmpv6_code_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147499266)
+        obj.value = reader.read("!B")[0]
+        obj.value_mask = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("icmpv6_code_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147499266] = icmpv6_code_masked
+
+class icmpv6_type(oxm):
+    type_len = 2147498497
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = icmpv6_type()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147498497)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("icmpv6_type {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147498497] = icmpv6_type
+
+class icmpv6_type_masked(oxm):
+    type_len = 2147498754
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        packed.append(struct.pack("!B", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = icmpv6_type_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147498754)
+        obj.value = reader.read("!B")[0]
+        obj.value_mask = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("icmpv6_type_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147498754] = icmpv6_type_masked
+
+class in_phy_port(oxm):
+    type_len = 2147484164
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(util.pack_port_no(self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = in_phy_port()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147484164)
+        obj.value = util.unpack_port_no(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("in_phy_port {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_port(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147484164] = in_phy_port
+
+class in_phy_port_masked(oxm):
+    type_len = 2147484424
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(util.pack_port_no(self.value))
+        packed.append(util.pack_port_no(self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = in_phy_port_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147484424)
+        obj.value = util.unpack_port_no(reader)
+        obj.value_mask = util.unpack_port_no(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("in_phy_port_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_port(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_port(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147484424] = in_phy_port_masked
+
+class in_port(oxm):
+    type_len = 2147483652
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(util.pack_port_no(self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = in_port()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147483652)
+        obj.value = util.unpack_port_no(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("in_port {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_port(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147483652] = in_port
+
+class in_port_masked(oxm):
+    type_len = 2147483912
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(util.pack_port_no(self.value))
+        packed.append(util.pack_port_no(self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = in_port_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147483912)
+        obj.value = util.unpack_port_no(reader)
+        obj.value_mask = util.unpack_port_no(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("in_port_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_port(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_port(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147483912] = in_port_masked
+
+class ip_dscp(oxm):
+    type_len = 2147487745
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ip_dscp()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147487745)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ip_dscp {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147487745] = ip_dscp
+
+class ip_dscp_masked(oxm):
+    type_len = 2147488002
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        packed.append(struct.pack("!B", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ip_dscp_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147488002)
+        obj.value = reader.read("!B")[0]
+        obj.value_mask = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ip_dscp_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147488002] = ip_dscp_masked
+
+class ip_ecn(oxm):
+    type_len = 2147488257
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ip_ecn()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147488257)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ip_ecn {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147488257] = ip_ecn
+
+class ip_ecn_masked(oxm):
+    type_len = 2147488514
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        packed.append(struct.pack("!B", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ip_ecn_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147488514)
+        obj.value = reader.read("!B")[0]
+        obj.value_mask = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ip_ecn_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147488514] = ip_ecn_masked
+
+class ip_proto(oxm):
+    type_len = 2147488769
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ip_proto()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147488769)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ip_proto {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147488769] = ip_proto
+
+class ip_proto_masked(oxm):
+    type_len = 2147489026
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        packed.append(struct.pack("!B", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ip_proto_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147489026)
+        obj.value = reader.read("!B")[0]
+        obj.value_mask = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ip_proto_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147489026] = ip_proto_masked
+
+class ipv4_dst(oxm):
+    type_len = 2147489796
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv4_dst()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147489796)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv4_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147489796] = ipv4_dst
+
+class ipv4_dst_masked(oxm):
+    type_len = 2147490056
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv4_dst_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147490056)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv4_dst_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_ipv4(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147490056] = ipv4_dst_masked
+
+class ipv4_src(oxm):
+    type_len = 2147489284
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv4_src()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147489284)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv4_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147489284] = ipv4_src
+
+class ipv4_src_masked(oxm):
+    type_len = 2147489544
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv4_src_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147489544)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv4_src_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_ipv4(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147489544] = ipv4_src_masked
+
+class ipv6_dst(oxm):
+    type_len = 2147497488
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!16s", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_dst()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147497488)
+        obj.value = reader.read('!16s')[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147497488] = ipv6_dst
+
+class ipv6_dst_masked(oxm):
+    type_len = 2147497760
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!16s", self.value))
+        packed.append(struct.pack("!16s", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_dst_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147497760)
+        obj.value = reader.read('!16s')[0]
+        obj.value_mask = reader.read('!16s')[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_dst_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.pp(self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147497760] = ipv6_dst_masked
+
+class ipv6_flabel(oxm):
+    type_len = 2147497988
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_flabel()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147497988)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_flabel {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147497988] = ipv6_flabel
+
+class ipv6_flabel_masked(oxm):
+    type_len = 2147498248
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_flabel_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147498248)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_flabel_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147498248] = ipv6_flabel_masked
+
+class ipv6_nd_sll(oxm):
+    type_len = 2147500038
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_nd_sll()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147500038)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_nd_sll {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147500038] = ipv6_nd_sll
+
+class ipv6_nd_sll_masked(oxm):
+    type_len = 2147500300
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        packed.append(struct.pack("!6B", *self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_nd_sll_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147500300)
+        obj.value = list(reader.read('!6B'))
+        obj.value_mask = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_nd_sll_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_mac(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147500300] = ipv6_nd_sll_masked
+
+class ipv6_nd_target(oxm):
+    type_len = 2147499536
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!16s", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_nd_target()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147499536)
+        obj.value = reader.read('!16s')[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_nd_target {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147499536] = ipv6_nd_target
+
+class ipv6_nd_target_masked(oxm):
+    type_len = 2147499808
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!16s", self.value))
+        packed.append(struct.pack("!16s", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_nd_target_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147499808)
+        obj.value = reader.read('!16s')[0]
+        obj.value_mask = reader.read('!16s')[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_nd_target_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.pp(self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147499808] = ipv6_nd_target_masked
+
+class ipv6_nd_tll(oxm):
+    type_len = 2147500550
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_nd_tll()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147500550)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_nd_tll {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147500550] = ipv6_nd_tll
+
+class ipv6_nd_tll_masked(oxm):
+    type_len = 2147500812
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        packed.append(struct.pack("!6B", *self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_nd_tll_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147500812)
+        obj.value = list(reader.read('!6B'))
+        obj.value_mask = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_nd_tll_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_mac(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147500812] = ipv6_nd_tll_masked
+
+class ipv6_src(oxm):
+    type_len = 2147496976
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!16s", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_src()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147496976)
+        obj.value = reader.read('!16s')[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147496976] = ipv6_src
+
+class ipv6_src_masked(oxm):
+    type_len = 2147497248
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!16s", self.value))
+        packed.append(struct.pack("!16s", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_src_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147497248)
+        obj.value = reader.read('!16s')[0]
+        obj.value_mask = reader.read('!16s')[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_src_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.pp(self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147497248] = ipv6_src_masked
+
+class metadata(oxm):
+    type_len = 2147484680
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!Q", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = metadata()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147484680)
+        obj.value = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("metadata {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147484680] = metadata
+
+class metadata_masked(oxm):
+    type_len = 2147484944
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!Q", self.value))
+        packed.append(struct.pack("!Q", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = metadata_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147484944)
+        obj.value = reader.read("!Q")[0]
+        obj.value_mask = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("metadata_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147484944] = metadata_masked
+
+class mpls_label(oxm):
+    type_len = 2147501060
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = mpls_label()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147501060)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("mpls_label {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147501060] = mpls_label
+
+class mpls_label_masked(oxm):
+    type_len = 2147501320
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = mpls_label_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147501320)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("mpls_label_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147501320] = mpls_label_masked
+
+class mpls_tc(oxm):
+    type_len = 2147501569
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = mpls_tc()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147501569)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("mpls_tc {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147501569] = mpls_tc
+
+class mpls_tc_masked(oxm):
+    type_len = 2147501826
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        packed.append(struct.pack("!B", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = mpls_tc_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147501826)
+        obj.value = reader.read("!B")[0]
+        obj.value_mask = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("mpls_tc_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147501826] = mpls_tc_masked
+
+class sctp_dst(oxm):
+    type_len = 2147492866
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = sctp_dst()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147492866)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("sctp_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147492866] = sctp_dst
+
+class sctp_dst_masked(oxm):
+    type_len = 2147493124
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        packed.append(struct.pack("!H", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = sctp_dst_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147493124)
+        obj.value = reader.read("!H")[0]
+        obj.value_mask = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("sctp_dst_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147493124] = sctp_dst_masked
+
+class sctp_src(oxm):
+    type_len = 2147492354
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = sctp_src()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147492354)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("sctp_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147492354] = sctp_src
+
+class sctp_src_masked(oxm):
+    type_len = 2147492612
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        packed.append(struct.pack("!H", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = sctp_src_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147492612)
+        obj.value = reader.read("!H")[0]
+        obj.value_mask = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("sctp_src_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147492612] = sctp_src_masked
+
+class tcp_dst(oxm):
+    type_len = 2147490818
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = tcp_dst()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147490818)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("tcp_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147490818] = tcp_dst
+
+class tcp_dst_masked(oxm):
+    type_len = 2147491076
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        packed.append(struct.pack("!H", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = tcp_dst_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147491076)
+        obj.value = reader.read("!H")[0]
+        obj.value_mask = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("tcp_dst_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147491076] = tcp_dst_masked
+
+class tcp_src(oxm):
+    type_len = 2147490306
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = tcp_src()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147490306)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("tcp_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147490306] = tcp_src
+
+class tcp_src_masked(oxm):
+    type_len = 2147490564
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        packed.append(struct.pack("!H", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = tcp_src_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147490564)
+        obj.value = reader.read("!H")[0]
+        obj.value_mask = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("tcp_src_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147490564] = tcp_src_masked
+
+class tunnel_ipv4_dst(oxm):
+    type_len = 81924
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = tunnel_ipv4_dst()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 81924)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("tunnel_ipv4_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[81924] = tunnel_ipv4_dst
+
+class tunnel_ipv4_dst_masked(oxm):
+    type_len = 82184
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = tunnel_ipv4_dst_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 82184)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("tunnel_ipv4_dst_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_ipv4(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[82184] = tunnel_ipv4_dst_masked
+
+class tunnel_ipv4_src(oxm):
+    type_len = 81412
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = tunnel_ipv4_src()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 81412)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("tunnel_ipv4_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[81412] = tunnel_ipv4_src
+
+class tunnel_ipv4_src_masked(oxm):
+    type_len = 81672
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = tunnel_ipv4_src_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 81672)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("tunnel_ipv4_src_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_ipv4(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[81672] = tunnel_ipv4_src_masked
+
+class udp_dst(oxm):
+    type_len = 2147491842
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = udp_dst()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147491842)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("udp_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147491842] = udp_dst
+
+class udp_dst_masked(oxm):
+    type_len = 2147492100
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        packed.append(struct.pack("!H", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = udp_dst_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147492100)
+        obj.value = reader.read("!H")[0]
+        obj.value_mask = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("udp_dst_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147492100] = udp_dst_masked
+
+class udp_src(oxm):
+    type_len = 2147491330
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = udp_src()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147491330)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("udp_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147491330] = udp_src
+
+class udp_src_masked(oxm):
+    type_len = 2147491588
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        packed.append(struct.pack("!H", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = udp_src_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147491588)
+        obj.value = reader.read("!H")[0]
+        obj.value_mask = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("udp_src_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147491588] = udp_src_masked
+
+class vlan_pcp(oxm):
+    type_len = 2147487233
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = vlan_pcp()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147487233)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("vlan_pcp {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147487233] = vlan_pcp
+
+class vlan_pcp_masked(oxm):
+    type_len = 2147487490
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        packed.append(struct.pack("!B", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = vlan_pcp_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147487490)
+        obj.value = reader.read("!B")[0]
+        obj.value_mask = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("vlan_pcp_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147487490] = vlan_pcp_masked
+
+class vlan_vid(oxm):
+    type_len = 2147486722
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = vlan_vid()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147486722)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("vlan_vid {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147486722] = vlan_vid
+
+class vlan_vid_masked(oxm):
+    type_len = 2147486980
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        packed.append(struct.pack("!H", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = vlan_vid_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147486980)
+        obj.value = reader.read("!H")[0]
+        obj.value_mask = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("vlan_vid_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147486980] = vlan_vid_masked
+
+
diff --git a/Fabric/Utilities/src/python/loxi/of12/util.py b/Fabric/Utilities/src/python/loxi/of12/util.py
new file mode 100644
index 0000000..fd07b5f
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of12/util.py
@@ -0,0 +1,136 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+# Automatically generated by LOXI from template util.py
+# Do not modify
+
+import struct
+import loxi
+import const
+import common
+import action
+import instruction
+import oxm
+
+def pretty_mac(mac):
+    return ':'.join(["%02x" % x for x in mac])
+
+def pretty_ipv4(v):
+    return "%d.%d.%d.%d" % ((v >> 24) & 0xFF, (v >> 16) & 0xFF, (v >> 8) & 0xFF, v & 0xFF)
+
+def pretty_flags(v, flag_names):
+    set_flags = []
+    for flag_name in flag_names:
+        flag_value = getattr(const, flag_name)
+        if v & flag_value == flag_value:
+            set_flags.append(flag_name)
+        elif v & flag_value:
+            set_flags.append('%s&%#x' % (flag_name, v & flag_value))
+        v &= ~flag_value
+    if v:
+        set_flags.append("%#x" % v)
+    return '|'.join(set_flags) or '0'
+
+
+def pretty_port(v):
+    named_ports = [(k,v2) for (k,v2) in const.__dict__.iteritems() if k.startswith('OFPP_')]
+    for (k, v2) in named_ports:
+        if v == v2:
+            return k
+    return v
+
+def pack_port_no(value):
+    return struct.pack("!L", value)
+
+def unpack_port_no(reader):
+    return reader.read("!L")[0]
+
+def pack_fm_cmd(value):
+    return struct.pack("!B", value)
+
+def unpack_fm_cmd(reader):
+    return reader.read("!B")[0]
+
+def init_wc_bmap():
+    return 0
+
+def pack_wc_bmap(value):
+    return struct.pack("!Q", value)
+
+def unpack_wc_bmap(reader):
+    return reader.read("!Q")[0]
+
+def init_match_bmap():
+    return 0
+
+def pack_match_bmap(value):
+    return struct.pack("!Q", value)
+
+def unpack_match_bmap(reader):
+    return reader.read("!Q")[0]
+
+MASK64 = (1 << 64) - 1
+
+def pack_bitmap_128(value):
+    x = 0l
+    for y in value:
+        x |= 1 << y
+    return struct.pack("!QQ", (x >> 64) & MASK64, x & MASK64)
+
+def unpack_bitmap_128(reader):
+    hi, lo = reader.read("!QQ")
+    x = (hi << 64) | lo
+    i = 0
+    value = set()
+    while x != 0:
+        if x & 1 == 1:
+            value.add(i)
+        i += 1
+        x >>= 1
+    return value
+
+def pack_bitmap_512(value):
+    words = [0] * 8
+    for v in value:
+        assert v < 512
+        words[7-v/64] |= 1 << (v % 64)
+    return struct.pack("!8Q", *words)
+
+def unpack_bitmap_512(reader):
+    words = reader.read("!8Q")
+    x = 0l
+    for word in words:
+        x <<= 64
+        x |= word
+    i = 0
+    value = set()
+    while x != 0:
+        if x & 1 == 1:
+            value.add(i)
+        i += 1
+        x >>= 1
+    return value
+
+def pack_checksum_128(value):
+    return struct.pack("!QQ", (value >> 64) & MASK64, value & MASK64)
+
+def unpack_checksum_128(reader):
+    hi, lo = reader.read("!QQ")
+    return (hi << 64) | lo
diff --git a/Fabric/Utilities/src/python/loxi/of13/__init__.py b/Fabric/Utilities/src/python/loxi/of13/__init__.py
new file mode 100644
index 0000000..f4dc518
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of13/__init__.py
@@ -0,0 +1,37 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template init.py
+# Do not modify
+
+import const
+import bsn_tlv
+import meter_band
+import instruction
+import oxm
+import common
+import instruction_id
+import action
+import message
+import action_id
+from const import *
+from common import *
+from loxi import ProtocolError
diff --git a/Fabric/Utilities/src/python/loxi/of13/action.py b/Fabric/Utilities/src/python/loxi/of13/action.py
new file mode 100755
index 0000000..4875e74
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of13/action.py
@@ -0,0 +1,2205 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of13']
+
+class action(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = action.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = action()
+        obj.type = reader.read("!H")[0]
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("action {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class experimenter(action):
+    subtypes = {}
+
+    type = 65535
+
+    def __init__(self, experimenter=None, data=None):
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed.append(loxi.generic_util.pad_to(8, length))
+        length += len(packed[-1])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 4)
+        subclass = experimenter.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = experimenter()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.experimenter = reader.read("!L")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.experimenter != other.experimenter: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[65535] = experimenter
+"""
+class bsn(experimenter):
+    subtypes = {}
+
+    type = 65535
+    experimenter = 6035143
+
+    def __init__(self, subtype=None):
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 8)
+        subclass = bsn.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = bsn()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        obj.subtype = reader.read("!L")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+experimenter.subtypes[6035143] = bsn
+
+class bsn_checksum(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 4
+
+    def __init__(self, checksum=None):
+        if checksum != None:
+            self.checksum = checksum
+        else:
+            self.checksum = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(util.pack_checksum_128(self.checksum))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_checksum()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 4)
+        obj.checksum = util.unpack_checksum_128(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.checksum != other.checksum: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_checksum {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("checksum = ");
+                q.pp(self.checksum)
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[4] = bsn_checksum
+
+class bsn_gentable(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 5
+
+    def __init__(self, table_id=None, key=None):
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if key != None:
+            self.key = key
+        else:
+            self.key = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.table_id))
+        packed.append(loxi.generic_util.pack_list(self.key))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 5)
+        obj.table_id = reader.read("!L")[0]
+        obj.key = loxi.generic_util.unpack_list(reader, ofp.bsn_tlv.bsn_tlv.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.table_id != other.table_id: return False
+        if self.key != other.key: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("key = ");
+                q.pp(self.key)
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[5] = bsn_gentable
+
+class bsn_mirror(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 1
+
+    def __init__(self, dest_port=None, vlan_tag=None, copy_stage=None):
+        if dest_port != None:
+            self.dest_port = dest_port
+        else:
+            self.dest_port = 0
+        if vlan_tag != None:
+            self.vlan_tag = vlan_tag
+        else:
+            self.vlan_tag = 0
+        if copy_stage != None:
+            self.copy_stage = copy_stage
+        else:
+            self.copy_stage = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.dest_port))
+        packed.append(struct.pack("!L", self.vlan_tag))
+        packed.append(struct.pack("!B", self.copy_stage))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_mirror()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 1)
+        obj.dest_port = reader.read("!L")[0]
+        obj.vlan_tag = reader.read("!L")[0]
+        obj.copy_stage = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.dest_port != other.dest_port: return False
+        if self.vlan_tag != other.vlan_tag: return False
+        if self.copy_stage != other.copy_stage: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_mirror {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("dest_port = ");
+                q.text("%#x" % self.dest_port)
+                q.text(","); q.breakable()
+                q.text("vlan_tag = ");
+                q.text("%#x" % self.vlan_tag)
+                q.text(","); q.breakable()
+                q.text("copy_stage = ");
+                q.text("%#x" % self.copy_stage)
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[1] = bsn_mirror
+
+class bsn_set_tunnel_dst(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 2
+
+    def __init__(self, dst=None):
+        if dst != None:
+            self.dst = dst
+        else:
+            self.dst = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.dst))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_tunnel_dst()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 2)
+        obj.dst = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.dst != other.dst: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_tunnel_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("dst = ");
+                q.text("%#x" % self.dst)
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[2] = bsn_set_tunnel_dst
+"""
+
+class copy_ttl_in(action):
+    type = 12
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = copy_ttl_in()
+        _type = reader.read("!H")[0]
+        assert(_type == 12)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("copy_ttl_in {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action.subtypes[12] = copy_ttl_in
+
+class copy_ttl_out(action):
+    type = 11
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = copy_ttl_out()
+        _type = reader.read("!H")[0]
+        assert(_type == 11)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("copy_ttl_out {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action.subtypes[11] = copy_ttl_out
+
+class dec_mpls_ttl(action):
+    type = 16
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = dec_mpls_ttl()
+        _type = reader.read("!H")[0]
+        assert(_type == 16)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("dec_mpls_ttl {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action.subtypes[16] = dec_mpls_ttl
+
+class dec_nw_ttl(action):
+    type = 24
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = dec_nw_ttl()
+        _type = reader.read("!H")[0]
+        assert(_type == 24)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("dec_nw_ttl {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action.subtypes[24] = dec_nw_ttl
+
+class group(action):
+    type = 22
+
+    def __init__(self, group_id=None):
+        if group_id != None:
+            self.group_id = group_id
+        else:
+            self.group_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.group_id))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group()
+        _type = reader.read("!H")[0]
+        assert(_type == 22)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.group_id = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.group_id != other.group_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("group_id = ");
+                q.text("%#x" % self.group_id)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[22] = group
+"""
+class nicira(experimenter):
+    subtypes = {}
+
+    type = 65535
+    experimenter = 8992
+
+    def __init__(self, subtype=None):
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!H", self.subtype))
+        packed.append('\x00' * 2)
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 8)
+        subclass = nicira.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = nicira()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 8992)
+        obj.subtype = reader.read("!H")[0]
+        reader.skip(2)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("nicira {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+experimenter.subtypes[8992] = nicira
+
+class nicira_dec_ttl(nicira):
+    type = 65535
+    experimenter = 8992
+    subtype = 18
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!H", self.subtype))
+        packed.append('\x00' * 2)
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = nicira_dec_ttl()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 8992)
+        _subtype = reader.read("!H")[0]
+        assert(_subtype == 18)
+        reader.skip(2)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("nicira_dec_ttl {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+nicira.subtypes[18] = nicira_dec_ttl
+"""
+class output(action):
+    type = 0
+
+    def __init__(self, port=None, max_len=None):
+        if port != None:
+            self.port = port
+        else:
+            self.port = 0
+        if max_len != None:
+            self.max_len = max_len
+        else:
+            self.max_len = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(util.pack_port_no(self.port))
+        packed.append(struct.pack("!H", self.max_len))
+        packed.append('\x00' * 6)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = output()
+        _type = reader.read("!H")[0]
+        assert(_type == 0)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.port = util.unpack_port_no(reader)
+        obj.max_len = reader.read("!H")[0]
+        reader.skip(6)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.port != other.port: return False
+        if self.max_len != other.max_len: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("output {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("port = ");
+                q.text(util.pretty_port(self.port))
+                q.text(","); q.breakable()
+                q.text("max_len = ");
+                q.text("%#x" % self.max_len)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[0] = output
+
+class pop_mpls(action):
+    type = 20
+
+    def __init__(self, ethertype=None):
+        if ethertype != None:
+            self.ethertype = ethertype
+        else:
+            self.ethertype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!H", self.ethertype))
+        packed.append('\x00' * 2)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = pop_mpls()
+        _type = reader.read("!H")[0]
+        assert(_type == 20)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.ethertype = reader.read("!H")[0]
+        reader.skip(2)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.ethertype != other.ethertype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("pop_mpls {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("ethertype = ");
+                q.text("%#x" % self.ethertype)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[20] = pop_mpls
+
+class pop_pbb(action):
+    type = 27
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = pop_pbb()
+        _type = reader.read("!H")[0]
+        assert(_type == 27)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("pop_pbb {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action.subtypes[27] = pop_pbb
+
+class pop_vlan(action):
+    type = 18
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = pop_vlan()
+        _type = reader.read("!H")[0]
+        assert(_type == 18)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("pop_vlan {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action.subtypes[18] = pop_vlan
+
+class push_mpls(action):
+    type = 19
+
+    def __init__(self, ethertype=None):
+        if ethertype != None:
+            self.ethertype = ethertype
+        else:
+            self.ethertype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!H", self.ethertype))
+        packed.append('\x00' * 2)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = push_mpls()
+        _type = reader.read("!H")[0]
+        assert(_type == 19)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.ethertype = reader.read("!H")[0]
+        reader.skip(2)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.ethertype != other.ethertype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("push_mpls {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("ethertype = ");
+                q.text("%#x" % self.ethertype)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[19] = push_mpls
+
+class push_pbb(action):
+    type = 26
+
+    def __init__(self, ethertype=None):
+        if ethertype != None:
+            self.ethertype = ethertype
+        else:
+            self.ethertype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!H", self.ethertype))
+        packed.append('\x00' * 2)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = push_pbb()
+        _type = reader.read("!H")[0]
+        assert(_type == 26)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.ethertype = reader.read("!H")[0]
+        reader.skip(2)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.ethertype != other.ethertype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("push_pbb {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("ethertype = ");
+                q.text("%#x" % self.ethertype)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[26] = push_pbb
+
+class push_vlan(action):
+    type = 17
+
+    def __init__(self, ethertype=None):
+        if ethertype != None:
+            self.ethertype = ethertype
+        else:
+            self.ethertype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!H", self.ethertype))
+        packed.append('\x00' * 2)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = push_vlan()
+        _type = reader.read("!H")[0]
+        assert(_type == 17)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.ethertype = reader.read("!H")[0]
+        reader.skip(2)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.ethertype != other.ethertype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("push_vlan {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("ethertype = ");
+                q.text("%#x" % self.ethertype)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[17] = push_vlan
+
+class set_field(action):
+    type = 25
+
+    def __init__(self, field=None):
+        if field != None:
+            self.field = field
+        else:
+            self.field = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(self.field.pack())
+        length = sum([len(x) for x in packed])
+        packed.append(loxi.generic_util.pad_to(8, length))
+        length += len(packed[-1])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_field()
+        _type = reader.read("!H")[0]
+        assert(_type == 25)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.field = ofp.oxm.oxm.unpack(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.field != other.field: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_field {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("field = ");
+                q.pp(self.field)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[25] = set_field
+
+class set_mpls_ttl(action):
+    type = 15
+
+    def __init__(self, mpls_ttl=None):
+        if mpls_ttl != None:
+            self.mpls_ttl = mpls_ttl
+        else:
+            self.mpls_ttl = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!B", self.mpls_ttl))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_mpls_ttl()
+        _type = reader.read("!H")[0]
+        assert(_type == 15)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.mpls_ttl = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.mpls_ttl != other.mpls_ttl: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_mpls_ttl {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("mpls_ttl = ");
+                q.text("%#x" % self.mpls_ttl)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[15] = set_mpls_ttl
+
+class set_nw_ttl(action):
+    type = 23
+
+    def __init__(self, nw_ttl=None):
+        if nw_ttl != None:
+            self.nw_ttl = nw_ttl
+        else:
+            self.nw_ttl = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!B", self.nw_ttl))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_nw_ttl()
+        _type = reader.read("!H")[0]
+        assert(_type == 23)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.nw_ttl = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.nw_ttl != other.nw_ttl: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_nw_ttl {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("nw_ttl = ");
+                q.text("%#x" % self.nw_ttl)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[23] = set_nw_ttl
+
+class set_queue(action):
+    type = 21
+
+    def __init__(self, queue_id=None):
+        if queue_id != None:
+            self.queue_id = queue_id
+        else:
+            self.queue_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.queue_id))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_queue()
+        _type = reader.read("!H")[0]
+        assert(_type == 21)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.queue_id = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.queue_id != other.queue_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_queue {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("queue_id = ");
+                q.text("%#x" % self.queue_id)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[21] = set_queue
+
+OFDPA_EXPERIMETER =0x00001018
+
+class ofdpa(experimenter):
+    subtypes = {}
+
+    type = 65535
+    experimenter = OFDPA_EXPERIMETER
+
+    def __init__(self, subtype=None):
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!H", self.subtype))
+        packed.append('\x00' * 6)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        #8 is offset, ref OFReader
+        subtype, = reader.peek('!H', 8)
+        subclass = ofdpa.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = ofdpa()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == OFDPA_EXPERIMETER)
+        obj.subtype = reader.read("!H")[0]
+        reader.skip(6)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ofdpa {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+experimenter.subtypes[OFDPA_EXPERIMETER] = ofdpa
+
+OFDPA_ACT_PUSH_L2_HEADER=1
+OFDPA_ACT_POP_L2_HEADER=2 
+OFDPA_ACT_PUSH_CW=3 
+OFDPA_ACT_POP_CW=4
+OFDPA_ACT_COPY_TC_IN=5
+OFDPA_ACT_COPY_TC_OUT=6
+OFDPA_ACT_SET_TC_FROM_TABLE=7
+OFDPA_ACT_SET_PCP_DFI_FROM_TABLE=9
+OFDPA_ACT_OAM_LM_RX_COUNT=10
+OFDPA_ACT_OAM_LM_TX_COUNT=11
+OFDPA_ACT_OAM_SET_COUNTER_FIELDS=12
+OFDPA_ACT_DEC_TTL_MTU=13
+OFDPA_ACT_CHECK_DROP_STATUS=14
+OFDPA_ACT_SET_QOS_FROM_TABLE=15
+
+
+class ofdpa_push_l2_header(ofdpa):
+    type = 65535
+    experimenter = OFDPA_EXPERIMETER
+    subtype = OFDPA_ACT_PUSH_L2_HEADER
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!H", self.subtype))
+        packed.append('\x00' * 6)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ofdpa_push_l2_header()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == OFDPA_EXPERIMETER)
+        _subtype = reader.read("!H")[0]
+        assert(_subtype == OFDPA_ACT_PUSH_L2_HEADER)   
+        reader.skip(6)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ofdpa_push_l2_header {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("ofdpa_push_l2_header");
+            q.breakable()
+        q.text('}')
+
+ofdpa.subtypes[OFDPA_ACT_PUSH_L2_HEADER] = ofdpa_push_l2_header
+
+class ofdpa_pop_l2_header(ofdpa):
+    type = 65535
+    experimenter = OFDPA_EXPERIMETER
+    subtype = OFDPA_ACT_POP_L2_HEADER
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!H", self.subtype))
+        packed.append('\x00' * 6)        
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ofdpa_pop_l2_header()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == OFDPA_EXPERIMETER)
+        _subtype = reader.read("!H")[0]
+        assert(_subtype == OFDPA_ACT_POP_L2_HEADER)          
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ofdpa_pop_l2_header {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("ofdpa_pop_l2_header");
+            q.breakable()
+        q.text('}')
+
+ofdpa.subtypes[OFDPA_ACT_POP_L2_HEADER] = ofdpa_pop_l2_header
+
+class ofdpa_push_cw(ofdpa):
+    type = 65535
+    experimenter = OFDPA_EXPERIMETER
+    subtype = OFDPA_ACT_PUSH_CW
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!H", self.subtype))
+        packed.append('\x00' * 6)        
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ofdpa_push_cw()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == OFDPA_EXPERIMETER)
+        _subtype = reader.read("!H")[0]
+        assert(_subtype == OFDPA_ACT_PUSH_CW)          
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ofdpa_push_cw {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("ofdpa_push_cw");
+            q.breakable()
+        q.text('}')
+
+ofdpa.subtypes[OFDPA_ACT_PUSH_CW] = ofdpa_push_cw
+
+class ofdpa_pop_cw(ofdpa):
+    type = 65535
+    experimenter = OFDPA_EXPERIMETER
+    subtype = OFDPA_ACT_POP_CW
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!H", self.subtype))
+        packed.append('\x00' * 6)        
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ofdpa_pop_cw()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == OFDPA_EXPERIMETER)
+        _subtype = reader.read("!H")[0]
+        assert(_subtype == OFDPA_ACT_POP_CW)          
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ofdpa_pop_cw {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("ofdpa_pop_cw");
+            q.breakable()
+        q.text('}')
+
+ofdpa.subtypes[OFDPA_ACT_POP_CW] = ofdpa_pop_cw
+
+class ofdpa_copy_tc_in(ofdpa):
+    type = 65535
+    experimenter = OFDPA_EXPERIMETER
+    subtype = OFDPA_ACT_COPY_TC_IN
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!H", self.subtype))
+        packed.append('\x00' * 6)        
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ofdpa_copy_tc_in()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == OFDPA_EXPERIMETER)
+        _subtype = reader.read("!H")[0]
+        assert(_subtype == OFDPA_ACT_COPY_TC_IN)  
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ofdpa_copy_tc_in {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("ofdpa_copy_tc_in");
+            q.breakable()
+        q.text('}')
+
+ofdpa.subtypes[OFDPA_ACT_COPY_TC_IN] = ofdpa_copy_tc_in
+
+class ofdpa_copy_tc_out(ofdpa):
+    type = 65535
+    experimenter = OFDPA_EXPERIMETER
+    subtype = OFDPA_ACT_COPY_TC_OUT
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!H", self.subtype))
+        packed.append('\x00' * 6)        
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ofdpa_copy_tc_out()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == OFDPA_EXPERIMETER)
+        _subtype = reader.read("!H")[0]
+        assert(_subtype == OFDPA_ACT_COPY_TC_OUT)        
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ofdpa_copy_tc_out {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("ofdpa_copy_tc_out");
+            q.breakable()
+        q.text('}')
+
+ofdpa.subtypes[OFDPA_ACT_COPY_TC_OUT] = ofdpa_copy_tc_out
+
+class ofdpa_dec_ttl_mtu(ofdpa):
+    type = 65535
+    experimenter = OFDPA_EXPERIMETER
+    subtype = OFDPA_ACT_DEC_TTL_MTU
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!H", self.subtype))
+        packed.append('\x00' * 6)        
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ofdpa_dec_ttl_mtu()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == OFDPA_EXPERIMETER)
+        _subtype = reader.read("!H")[0]
+        assert(_subtype == OFDPA_ACT_DEC_TTL_MTU)        
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ofdpa_dec_ttl_mtu {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("ofdpa_dec_ttl_mtu");
+            q.breakable()
+        q.text('}')
+
+ofdpa.subtypes[OFDPA_ACT_DEC_TTL_MTU] = ofdpa_dec_ttl_mtu
+
+class ofdpa_set_tc_from_table(ofdpa):
+    type = 65535
+    experimenter = OFDPA_EXPERIMETER
+    subtype = OFDPA_ACT_SET_TC_FROM_TABLE
+
+    def __init__(self, qos_index=None):
+        if qos_index != None:
+            self.qos_index = qos_index
+        else:
+            self.qos_index = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!H", self.subtype))
+        packed.append(struct.pack("!B", self.qos_index))
+        packed.append('\x00' * 5)        
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ofdpa_set_tc_from_table()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == OFDPA_EXPERIMETER)
+        _subtype = reader.read("!H")[0]
+        assert(_subtype == OFDPA_ACT_SET_TC_FROM_TABLE)
+        obj.qos_index = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.qos_index != other.qos_index: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ofdpa_set_tc_from_table {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("ofdpa_set_tc_from_table");
+                q.pp(self.qos_index)
+            q.breakable()
+        q.text('}')
+
+ofdpa.subtypes[OFDPA_ACT_SET_TC_FROM_TABLE] = ofdpa_set_tc_from_table
+
+
+class ofdpa_set_pcp_dfi_from_table(ofdpa):
+    type = 65535
+    experimenter = OFDPA_EXPERIMETER
+    subtype = OFDPA_ACT_SET_PCP_DFI_FROM_TABLE
+
+    def __init__(self, qos_index=None):
+        if qos_index != None:
+            self.qos_index = qos_index
+        else:
+            self.qos_index = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!H", self.subtype))
+        packed.append(struct.pack("!B", self.qos_index))
+        packed.append('\x00' * 5)         
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ofdpa_set_pcp_dfi_from_table()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == OFDPA_EXPERIMETER)
+        _subtype = reader.read("!H")[0]
+        assert(_subtype == OFDPA_ACT_SET_PCP_DFI_FROM_TABLE)
+        obj.qos_index = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.qos_index != other.qos_index: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ofdpa_set_pcp_dfi_from_table {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("ofdpa_set_pcp_dfi_from_table");
+                q.pp(self.qos_index)
+            q.breakable()
+        q.text('}')
+
+ofdpa.subtypes[OFDPA_ACT_SET_PCP_DFI_FROM_TABLE] = ofdpa_set_pcp_dfi_from_table
+
+
+class ofdpa_check_drop_status(ofdpa):
+    type = 65535
+    experimenter = OFDPA_EXPERIMETER
+    subtype = OFDPA_ACT_CHECK_DROP_STATUS
+
+    def __init__(self, index, status_type):
+        self.index = index
+        self.status_type  = status_type
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!H", self.subtype))
+        packed.append(struct.pack("!L", self.index))
+        packed.append(struct.pack("!B", self.status_type))  
+        packed.append('\x00' * 1)    
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ofdpa_check_drop_status()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == OFDPA_EXPERIMETER)
+        _subtype = reader.read("!H")[0]
+        assert(_subtype == OFDPA_ACT_CHECK_DROP_STATUS)
+        obj.status_type  = reader.read("!L")[0]
+        obj.index = reader.read("!B")[0]        
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.index != other.index: return False
+        if self.status_type != other.status_type: return False        
+        return True
+
+    def pretty_print(self, q):
+        q.text("ofdpa_check_drop_status {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("ofdpa_check_drop_status = ");
+                q.pp(self.index)
+                q.pp(self.status_type)                
+            q.breakable()
+        q.text('}')
+
+ofdpa.subtypes[OFDPA_ACT_CHECK_DROP_STATUS] = ofdpa_check_drop_status
+
+
+class ofdpa_set_qos_from_table(ofdpa):
+    type = 65535
+    experimenter = OFDPA_EXPERIMETER
+    subtype = OFDPA_ACT_SET_QOS_FROM_TABLE
+
+    def __init__(self, qos_index, mpls_tc):
+        self.qos_index = qos_index
+        self.mpls_tc  = mpls_tc
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!H", self.subtype))
+        packed.append(struct.pack("!B", self.qos_index))
+        packed.append(struct.pack("!B", self.mpls_tc))   
+        packed.append('\x00' * 4)           
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ofdpa_check_drop_status()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == OFDPA_EXPERIMETER)
+        _subtype = reader.read("!H")[0]
+        assert(_subtype == OFDPA_ACT_SET_QOS_FROM_TABLE)
+        obj.qos_index = reader.read("!B")[0]
+        obj.mpls_tc  = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.qos_index != other.qos_index: return False
+        if self.mpls_tc != other.mpls_tc: return False        
+        return True
+
+    def pretty_print(self, q):
+        q.text("ofdpa_set_qos_from_table {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("ofdpa_set_qos_from_table = ");
+                q.pp(self.qos_index)
+                q.pp(self.mpls_tc)                
+            q.breakable()
+        q.text('}')
+
+ofdpa.subtypes[OFDPA_ACT_SET_QOS_FROM_TABLE] = ofdpa_set_qos_from_table
+
+
+class ofdpa_oam_lm_tx_count(ofdpa):
+    type = 65535
+    experimenter = OFDPA_EXPERIMETER
+    subtype = OFDPA_ACT_OAM_LM_TX_COUNT
+
+    def __init__(self, lmep_id, traffic_class):
+        self.lmep_id = lmep_id
+        self.traffic_class  = traffic_class
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!H", self.subtype))
+        packed.append(struct.pack("!L", self.lmep_id))
+        packed.append(struct.pack("!B", self.traffic_class))   
+        packed.append('\x00' * 1)   
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ofdpa_check_drop_status()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == OFDPA_EXPERIMETER)
+        _subtype = reader.read("!H")[0]
+        assert(_subtype == OFDPA_ACT_OAM_LM_TX_COUNT)
+        obj.lmep_id = reader.read("!L")[0]
+        obj.traffic_class  = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.lmep_id != other.lmep_id: return False
+        if self.traffic_class != other.traffic_class: return False        
+        return True
+
+    def pretty_print(self, q):
+        q.text("ofdpa_oam_lm_tx_count {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("ofdpa_oam_lm_tx_count = ");
+                q.pp(self.lmep_id)
+                q.pp(self.traffic_class)                
+            q.breakable()
+        q.text('}')
+
+ofdpa.subtypes[OFDPA_ACT_OAM_LM_TX_COUNT] = ofdpa_oam_lm_tx_count
+
+class ofdpa_oam_lm_rx_count(ofdpa):
+    type = 65535
+    experimenter = OFDPA_EXPERIMETER
+    subtype = OFDPA_ACT_OAM_LM_RX_COUNT
+
+    def __init__(self, lmep_id, traffic_class):
+        self.lmep_id = lmep_id
+        self.traffic_class  = traffic_class
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!H", self.subtype))
+        packed.append(struct.pack("!L", self.lmep_id))
+        packed.append(struct.pack("!B", self.traffic_class))  
+        packed.append('\x00' * 1)   
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ofdpa_check_drop_status()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == OFDPA_EXPERIMETER)
+        _subtype = reader.read("!H")[0]
+        assert(_subtype == OFDPA_ACT_OAM_LM_RX_COUNT)
+        obj.lmep_id = reader.read("!L")[0]
+        obj.traffic_class  = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.lmep_id != other.lmep_id: return False
+        if self.traffic_class != other.traffic_class: return False        
+        return True
+
+    def pretty_print(self, q):
+        q.text("ofdpa_oam_lm_rx_count {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("ofdpa_oam_lm_rx_count = ");
+                q.pp(self.lmep_id)
+                q.pp(self.traffic_class)                
+            q.breakable()
+        q.text('}')
+
+ofdpa.subtypes[OFDPA_ACT_OAM_LM_RX_COUNT] = ofdpa_oam_lm_rx_count
+
+
+class ofdpa_oam_set_counter_field(ofdpa):
+    type = 65535
+    experimenter = OFDPA_EXPERIMETER
+    subtype = OFDPA_ACT_OAM_SET_COUNTER_FIELDS
+
+    def __init__(self, lmep_id, traffic_class):
+        self.lmep_id = lmep_id
+        self.traffic_class  = traffic_class
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!H", self.subtype))
+        packed.append(struct.pack("!L", self.lmep_id))
+        packed.append(struct.pack("!B", self.traffic_class))  
+        packed.append('\x00' * 1)   
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ofdpa_check_drop_status()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == OFDPA_EXPERIMETER)
+        _subtype = reader.read("!H")[0]
+        assert(_subtype == OFDPA_ACT_OAM_SET_COUNTER_FIELDS)
+        obj.lmep_id = reader.read("!L")[0]
+        obj.traffic_class  = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.lmep_id != other.lmep_id: return False
+        if self.traffic_class != other.traffic_class: return False        
+        return True
+
+    def pretty_print(self, q):
+        q.text("ofdpa_oam_set_counter_field {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("ofdpa_oam_set_counter_field = ");
+                q.pp(self.lmep_id)
+                q.pp(self.traffic_class)                
+            q.breakable()
+        q.text('}')
+
+ofdpa.subtypes[OFDPA_ACT_OAM_SET_COUNTER_FIELDS] = ofdpa_oam_set_counter_field
+
+class copy_field(action):
+    type = 65535
+    experimenter = 0x4f4e4600  # ONF_EXPERIMENTER_ID
+    exp_type = 3200            # ONFTFP_ET_WRITE_COPYFIELD
+
+    def __init__(self, n_bits=None, src_offset=None, dst_offset=None, oxm_ids=None):
+        if n_bits != None:
+            self.n_bits = n_bits
+        else:
+            self.n_bits = 0
+        if src_offset != None:
+            self.src_offset = src_offset
+        else:
+            self.src_offset = 0
+        if dst_offset != None:
+            self.dst_offset = dst_offset
+        else:
+            self.dst_offset = 0
+        if oxm_ids != None:
+            self.oxm_ids = oxm_ids
+        else:
+            self.oxm_ids = [ ]
+        return
+
+    def pack( self ):
+        packed = [ ]
+        packed.append( struct.pack( "!H", self.type ) )
+        packed.append( struct.pack( "!H", 0 ) )  # placeholder for len at index 1
+        packed.append( struct.pack( "!L", self.experimenter ) )
+        packed.append( struct.pack( "!H", self.exp_type ) )
+        packed.append( '\x00' * 2 )
+        packed.append( struct.pack( "!H", self.n_bits ) )
+        packed.append( struct.pack( "!H", self.src_offset ) )
+        packed.append( struct.pack( "!H", self.dst_offset ) )
+        packed.append( '\x00' * 2 )
+        packed.append( "".join(self.oxm_ids ) )
+        length = sum( [ len( x ) for x in packed ] )
+        packed[ 1 ] = struct.pack( "!H", length )
+        return ''.join( packed )
+
+    @staticmethod
+    def unpack( reader ):
+        obj = copy_field()
+        _type = reader.read( "!H" )[ 0 ]
+        _len = reader.read( "!H" )[ 0 ]
+        orig_reader = reader
+        reader = orig_reader.slice( _len, 4 )
+        obj.n_bits = reader.read( "!H" )[ 0 ]
+        obj.src_offset = reader.read( "!H" )[ 0 ]
+        obj.dst_offset = reader.read( "!H" )[ 0 ]
+        reader.skip( 2 )
+        obj.oxm_ids = loxi.generic_util.unpack_list( reader, ofp.oxm.oxm.unpack )
+        return obj
+
+    def __eq__( self, other ):
+        if type( self ) != type( other ): return False
+        if self.n_bits != other.n_bits: return False
+        if self.src_offset != other.src_offset: return False
+        if self.dst_offset != other.dst_offset: return False
+        if self.oxm_ids != other.oxm_ids: return False
+        return True
+
+    def pretty_print( self, q ):
+        q.text( "copy_field {" )
+        with q.group():
+            with q.indent( 2 ):
+                q.breakable()
+                q.text( "n_bits = " )
+                q.text( "%#x" % self.n_bits )
+                q.text( "," )
+                q.breakable()
+                q.text( "src_offset = " )
+                q.text( "%#x" % self.src_offset )
+                q.text( "," )
+                q.breakable()
+                q.text( "dst_offset = " )
+                q.text( "%#x" % self.dst_offset )
+                q.text( "," )
+                q.breakable()
+                q.text( "oxm_ids = " )
+                q.pp( self.oxm_ids )
+            q.breakable()
+        q.text( '}' )
diff --git a/Fabric/Utilities/src/python/loxi/of13/action_id.py b/Fabric/Utilities/src/python/loxi/of13/action_id.py
new file mode 100644
index 0000000..5814e31
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of13/action_id.py
@@ -0,0 +1,1082 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of13']
+
+class action_id(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = action_id.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = action_id()
+        obj.type = reader.read("!H")[0]
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("action_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class experimenter(action_id):
+    subtypes = {}
+
+    type = 65535
+
+    def __init__(self, experimenter=None):
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 4)
+        subclass = experimenter.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = experimenter()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.experimenter = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.experimenter != other.experimenter: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action_id.subtypes[65535] = experimenter
+
+class bsn(experimenter):
+    subtypes = {}
+
+    type = 65535
+    experimenter = 6035143
+
+    def __init__(self, subtype=None):
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 8)
+        subclass = bsn.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = bsn()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        obj.subtype = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+experimenter.subtypes[6035143] = bsn
+
+class bsn_checksum(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 4
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_checksum()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_checksum {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[4] = bsn_checksum
+
+class bsn_gentable(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 5
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 5)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[5] = bsn_gentable
+
+class bsn_mirror(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 1
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_mirror()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 1)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_mirror {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[1] = bsn_mirror
+
+class bsn_set_tunnel_dst(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 2
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_tunnel_dst()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 2)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_tunnel_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[2] = bsn_set_tunnel_dst
+
+class copy_ttl_in(action_id):
+    type = 12
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = copy_ttl_in()
+        _type = reader.read("!H")[0]
+        assert(_type == 12)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("copy_ttl_in {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action_id.subtypes[12] = copy_ttl_in
+
+class copy_ttl_out(action_id):
+    type = 11
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = copy_ttl_out()
+        _type = reader.read("!H")[0]
+        assert(_type == 11)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("copy_ttl_out {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action_id.subtypes[11] = copy_ttl_out
+
+class dec_mpls_ttl(action_id):
+    type = 16
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = dec_mpls_ttl()
+        _type = reader.read("!H")[0]
+        assert(_type == 16)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("dec_mpls_ttl {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action_id.subtypes[16] = dec_mpls_ttl
+
+class dec_nw_ttl(action_id):
+    type = 24
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = dec_nw_ttl()
+        _type = reader.read("!H")[0]
+        assert(_type == 24)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("dec_nw_ttl {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action_id.subtypes[24] = dec_nw_ttl
+
+class group(action_id):
+    type = 22
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group()
+        _type = reader.read("!H")[0]
+        assert(_type == 22)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action_id.subtypes[22] = group
+
+class nicira(experimenter):
+    subtypes = {}
+
+    type = 65535
+    experimenter = 8992
+
+    def __init__(self, subtype=None):
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!H", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 8)
+        subclass = nicira.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = nicira()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 8992)
+        obj.subtype = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("nicira {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+experimenter.subtypes[8992] = nicira
+
+class nicira_dec_ttl(nicira):
+    type = 65535
+    experimenter = 8992
+    subtype = 18
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!H", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = nicira_dec_ttl()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 8992)
+        _subtype = reader.read("!H")[0]
+        assert(_subtype == 18)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("nicira_dec_ttl {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+nicira.subtypes[18] = nicira_dec_ttl
+
+class output(action_id):
+    type = 0
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = output()
+        _type = reader.read("!H")[0]
+        assert(_type == 0)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("output {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action_id.subtypes[0] = output
+
+class pop_mpls(action_id):
+    type = 20
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = pop_mpls()
+        _type = reader.read("!H")[0]
+        assert(_type == 20)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("pop_mpls {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action_id.subtypes[20] = pop_mpls
+
+class pop_pbb(action_id):
+    type = 27
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = pop_pbb()
+        _type = reader.read("!H")[0]
+        assert(_type == 27)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("pop_pbb {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action_id.subtypes[27] = pop_pbb
+
+class pop_vlan(action_id):
+    type = 18
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = pop_vlan()
+        _type = reader.read("!H")[0]
+        assert(_type == 18)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("pop_vlan {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action_id.subtypes[18] = pop_vlan
+
+class push_mpls(action_id):
+    type = 19
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = push_mpls()
+        _type = reader.read("!H")[0]
+        assert(_type == 19)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("push_mpls {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action_id.subtypes[19] = push_mpls
+
+class push_pbb(action_id):
+    type = 26
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = push_pbb()
+        _type = reader.read("!H")[0]
+        assert(_type == 26)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("push_pbb {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action_id.subtypes[26] = push_pbb
+
+class push_vlan(action_id):
+    type = 17
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = push_vlan()
+        _type = reader.read("!H")[0]
+        assert(_type == 17)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("push_vlan {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action_id.subtypes[17] = push_vlan
+
+class set_field(action_id):
+    type = 25
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_field()
+        _type = reader.read("!H")[0]
+        assert(_type == 25)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_field {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action_id.subtypes[25] = set_field
+
+class set_mpls_ttl(action_id):
+    type = 15
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_mpls_ttl()
+        _type = reader.read("!H")[0]
+        assert(_type == 15)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_mpls_ttl {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action_id.subtypes[15] = set_mpls_ttl
+
+class set_nw_ttl(action_id):
+    type = 23
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_nw_ttl()
+        _type = reader.read("!H")[0]
+        assert(_type == 23)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_nw_ttl {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action_id.subtypes[23] = set_nw_ttl
+
+class set_queue(action_id):
+    type = 21
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_queue()
+        _type = reader.read("!H")[0]
+        assert(_type == 21)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_queue {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action_id.subtypes[21] = set_queue
+
+
diff --git a/Fabric/Utilities/src/python/loxi/of13/bsn_tlv.py b/Fabric/Utilities/src/python/loxi/of13/bsn_tlv.py
new file mode 100644
index 0000000..a9e4ff0
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of13/bsn_tlv.py
@@ -0,0 +1,3881 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of13']
+
+class bsn_tlv(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = bsn_tlv.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = bsn_tlv()
+        obj.type = reader.read("!H")[0]
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_tlv {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class actor_key(bsn_tlv):
+    type = 44
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = actor_key()
+        _type = reader.read("!H")[0]
+        assert(_type == 44)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("actor_key {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[44] = actor_key
+
+class actor_port_num(bsn_tlv):
+    type = 43
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = actor_port_num()
+        _type = reader.read("!H")[0]
+        assert(_type == 43)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("actor_port_num {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[43] = actor_port_num
+
+class actor_port_priority(bsn_tlv):
+    type = 42
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = actor_port_priority()
+        _type = reader.read("!H")[0]
+        assert(_type == 42)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("actor_port_priority {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[42] = actor_port_priority
+
+class actor_state(bsn_tlv):
+    type = 53
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!B", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = actor_state()
+        _type = reader.read("!H")[0]
+        assert(_type == 53)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("actor_state {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[53] = actor_state
+
+class actor_system_mac(bsn_tlv):
+    type = 41
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!6B", *self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = actor_system_mac()
+        _type = reader.read("!H")[0]
+        assert(_type == 41)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("actor_system_mac {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[41] = actor_system_mac
+
+class actor_system_priority(bsn_tlv):
+    type = 40
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = actor_system_priority()
+        _type = reader.read("!H")[0]
+        assert(_type == 40)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("actor_system_priority {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[40] = actor_system_priority
+
+class anchor(bsn_tlv):
+    type = 81
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = anchor()
+        _type = reader.read("!H")[0]
+        assert(_type == 81)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("anchor {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[81] = anchor
+
+class broadcast_query_timeout(bsn_tlv):
+    type = 10
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = broadcast_query_timeout()
+        _type = reader.read("!H")[0]
+        assert(_type == 10)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("broadcast_query_timeout {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[10] = broadcast_query_timeout
+
+class bucket(bsn_tlv):
+    type = 64
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(loxi.generic_util.pack_list(self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bucket()
+        _type = reader.read("!H")[0]
+        assert(_type == 64)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = loxi.generic_util.unpack_list(reader, ofp.bsn_tlv.bsn_tlv.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bucket {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[64] = bucket
+
+class circuit_id(bsn_tlv):
+    type = 14
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(self.value)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = circuit_id()
+        _type = reader.read("!H")[0]
+        assert(_type == 14)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("circuit_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[14] = circuit_id
+
+class convergence_status(bsn_tlv):
+    type = 45
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!B", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = convergence_status()
+        _type = reader.read("!H")[0]
+        assert(_type == 45)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("convergence_status {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[45] = convergence_status
+
+class crc_enabled(bsn_tlv):
+    type = 22
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!B", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = crc_enabled()
+        _type = reader.read("!H")[0]
+        assert(_type == 22)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("crc_enabled {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[22] = crc_enabled
+
+class data(bsn_tlv):
+    type = 55
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(self.value)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = data()
+        _type = reader.read("!H")[0]
+        assert(_type == 55)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("data {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[55] = data
+
+class eth_dst(bsn_tlv):
+    type = 33
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!6B", *self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = eth_dst()
+        _type = reader.read("!H")[0]
+        assert(_type == 33)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("eth_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[33] = eth_dst
+
+class eth_src(bsn_tlv):
+    type = 32
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!6B", *self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = eth_src()
+        _type = reader.read("!H")[0]
+        assert(_type == 32)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("eth_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[32] = eth_src
+
+class external_gateway_ip(bsn_tlv):
+    type = 26
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = external_gateway_ip()
+        _type = reader.read("!H")[0]
+        assert(_type == 26)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("external_gateway_ip {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[26] = external_gateway_ip
+
+class external_gateway_mac(bsn_tlv):
+    type = 29
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!6B", *self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = external_gateway_mac()
+        _type = reader.read("!H")[0]
+        assert(_type == 29)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("external_gateway_mac {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[29] = external_gateway_mac
+
+class external_ip(bsn_tlv):
+    type = 23
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = external_ip()
+        _type = reader.read("!H")[0]
+        assert(_type == 23)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("external_ip {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[23] = external_ip
+
+class external_mac(bsn_tlv):
+    type = 24
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!6B", *self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = external_mac()
+        _type = reader.read("!H")[0]
+        assert(_type == 24)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("external_mac {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[24] = external_mac
+
+class external_netmask(bsn_tlv):
+    type = 25
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = external_netmask()
+        _type = reader.read("!H")[0]
+        assert(_type == 25)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("external_netmask {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[25] = external_netmask
+
+class generation_id(bsn_tlv):
+    type = 80
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!Q", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = generation_id()
+        _type = reader.read("!H")[0]
+        assert(_type == 80)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("generation_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[80] = generation_id
+
+class header_size(bsn_tlv):
+    type = 31
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = header_size()
+        _type = reader.read("!H")[0]
+        assert(_type == 31)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("header_size {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[31] = header_size
+
+class icmp_code(bsn_tlv):
+    type = 69
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!B", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = icmp_code()
+        _type = reader.read("!H")[0]
+        assert(_type == 69)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("icmp_code {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[69] = icmp_code
+
+class icmp_id(bsn_tlv):
+    type = 70
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = icmp_id()
+        _type = reader.read("!H")[0]
+        assert(_type == 70)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("icmp_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[70] = icmp_id
+
+class icmp_type(bsn_tlv):
+    type = 68
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!B", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = icmp_type()
+        _type = reader.read("!H")[0]
+        assert(_type == 68)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("icmp_type {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[68] = icmp_type
+
+class idle_notification(bsn_tlv):
+    type = 7
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = idle_notification()
+        _type = reader.read("!H")[0]
+        assert(_type == 7)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("idle_notification {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[7] = idle_notification
+
+class idle_time(bsn_tlv):
+    type = 5
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!Q", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = idle_time()
+        _type = reader.read("!H")[0]
+        assert(_type == 5)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("idle_time {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[5] = idle_time
+
+class idle_timeout(bsn_tlv):
+    type = 8
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = idle_timeout()
+        _type = reader.read("!H")[0]
+        assert(_type == 8)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("idle_timeout {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[8] = idle_timeout
+
+class igmp_snooping(bsn_tlv):
+    type = 78
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = igmp_snooping()
+        _type = reader.read("!H")[0]
+        assert(_type == 78)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("igmp_snooping {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[78] = igmp_snooping
+
+class internal_gateway_mac(bsn_tlv):
+    type = 28
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!6B", *self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = internal_gateway_mac()
+        _type = reader.read("!H")[0]
+        assert(_type == 28)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("internal_gateway_mac {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[28] = internal_gateway_mac
+
+class internal_mac(bsn_tlv):
+    type = 27
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!6B", *self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = internal_mac()
+        _type = reader.read("!H")[0]
+        assert(_type == 27)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("internal_mac {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[27] = internal_mac
+
+class interval(bsn_tlv):
+    type = 58
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = interval()
+        _type = reader.read("!H")[0]
+        assert(_type == 58)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("interval {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[58] = interval
+
+class ip_proto(bsn_tlv):
+    type = 67
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!B", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ip_proto()
+        _type = reader.read("!H")[0]
+        assert(_type == 67)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ip_proto {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[67] = ip_proto
+
+class ipv4(bsn_tlv):
+    type = 4
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv4()
+        _type = reader.read("!H")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv4 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[4] = ipv4
+
+class ipv4_dst(bsn_tlv):
+    type = 35
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv4_dst()
+        _type = reader.read("!H")[0]
+        assert(_type == 35)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv4_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[35] = ipv4_dst
+
+class ipv4_netmask(bsn_tlv):
+    type = 60
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv4_netmask()
+        _type = reader.read("!H")[0]
+        assert(_type == 60)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv4_netmask {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[60] = ipv4_netmask
+
+class ipv4_src(bsn_tlv):
+    type = 34
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv4_src()
+        _type = reader.read("!H")[0]
+        assert(_type == 34)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv4_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[34] = ipv4_src
+
+class l2_multicast_lookup(bsn_tlv):
+    type = 79
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = l2_multicast_lookup()
+        _type = reader.read("!H")[0]
+        assert(_type == 79)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("l2_multicast_lookup {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[79] = l2_multicast_lookup
+
+class mac(bsn_tlv):
+    type = 1
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!6B", *self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = mac()
+        _type = reader.read("!H")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("mac {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[1] = mac
+
+class mac_mask(bsn_tlv):
+    type = 56
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!6B", *self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = mac_mask()
+        _type = reader.read("!H")[0]
+        assert(_type == 56)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("mac_mask {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[56] = mac_mask
+
+class miss_packets(bsn_tlv):
+    type = 13
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!Q", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = miss_packets()
+        _type = reader.read("!H")[0]
+        assert(_type == 13)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("miss_packets {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[13] = miss_packets
+
+class mpls_control_word(bsn_tlv):
+    type = 62
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!B", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = mpls_control_word()
+        _type = reader.read("!H")[0]
+        assert(_type == 62)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("mpls_control_word {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[62] = mpls_control_word
+
+class mpls_label(bsn_tlv):
+    type = 61
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = mpls_label()
+        _type = reader.read("!H")[0]
+        assert(_type == 61)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("mpls_label {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[61] = mpls_label
+
+class mpls_sequenced(bsn_tlv):
+    type = 63
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!B", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = mpls_sequenced()
+        _type = reader.read("!H")[0]
+        assert(_type == 63)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("mpls_sequenced {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[63] = mpls_sequenced
+
+class name(bsn_tlv):
+    type = 52
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(self.value)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = name()
+        _type = reader.read("!H")[0]
+        assert(_type == 52)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("name {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[52] = name
+
+class offset(bsn_tlv):
+    type = 82
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = offset()
+        _type = reader.read("!H")[0]
+        assert(_type == 82)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("offset {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[82] = offset
+
+class partner_key(bsn_tlv):
+    type = 51
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = partner_key()
+        _type = reader.read("!H")[0]
+        assert(_type == 51)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("partner_key {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[51] = partner_key
+
+class partner_port_num(bsn_tlv):
+    type = 50
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = partner_port_num()
+        _type = reader.read("!H")[0]
+        assert(_type == 50)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("partner_port_num {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[50] = partner_port_num
+
+class partner_port_priority(bsn_tlv):
+    type = 49
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = partner_port_priority()
+        _type = reader.read("!H")[0]
+        assert(_type == 49)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("partner_port_priority {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[49] = partner_port_priority
+
+class partner_state(bsn_tlv):
+    type = 54
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!B", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = partner_state()
+        _type = reader.read("!H")[0]
+        assert(_type == 54)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("partner_state {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[54] = partner_state
+
+class partner_system_mac(bsn_tlv):
+    type = 48
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!6B", *self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = partner_system_mac()
+        _type = reader.read("!H")[0]
+        assert(_type == 48)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("partner_system_mac {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[48] = partner_system_mac
+
+class partner_system_priority(bsn_tlv):
+    type = 47
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = partner_system_priority()
+        _type = reader.read("!H")[0]
+        assert(_type == 47)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("partner_system_priority {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[47] = partner_system_priority
+
+class port(bsn_tlv):
+    type = 0
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(util.pack_port_no(self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port()
+        _type = reader.read("!H")[0]
+        assert(_type == 0)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = util.unpack_port_no(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_port(self.value))
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[0] = port
+
+class priority(bsn_tlv):
+    type = 57
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = priority()
+        _type = reader.read("!H")[0]
+        assert(_type == 57)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("priority {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[57] = priority
+
+class queue_id(bsn_tlv):
+    type = 20
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_id()
+        _type = reader.read("!H")[0]
+        assert(_type == 20)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[20] = queue_id
+
+class queue_weight(bsn_tlv):
+    type = 21
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_weight()
+        _type = reader.read("!H")[0]
+        assert(_type == 21)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_weight {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[21] = queue_weight
+
+class reference(bsn_tlv):
+    type = 59
+
+    def __init__(self, table_id=None, key=None):
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if key != None:
+            self.key = key
+        else:
+            self.key = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.table_id))
+        packed.append(loxi.generic_util.pack_list(self.key))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = reference()
+        _type = reader.read("!H")[0]
+        assert(_type == 59)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.table_id = reader.read("!H")[0]
+        obj.key = loxi.generic_util.unpack_list(reader, ofp.bsn_tlv.bsn_tlv.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.table_id != other.table_id: return False
+        if self.key != other.key: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("reference {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("key = ");
+                q.pp(self.key)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[59] = reference
+
+class reply_packets(bsn_tlv):
+    type = 12
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!Q", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = reply_packets()
+        _type = reader.read("!H")[0]
+        assert(_type == 12)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("reply_packets {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[12] = reply_packets
+
+class request_packets(bsn_tlv):
+    type = 11
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!Q", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = request_packets()
+        _type = reader.read("!H")[0]
+        assert(_type == 11)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("request_packets {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[11] = request_packets
+
+class rx_bytes(bsn_tlv):
+    type = 71
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!Q", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = rx_bytes()
+        _type = reader.read("!H")[0]
+        assert(_type == 71)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("rx_bytes {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[71] = rx_bytes
+
+class rx_packets(bsn_tlv):
+    type = 2
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!Q", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = rx_packets()
+        _type = reader.read("!H")[0]
+        assert(_type == 2)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("rx_packets {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[2] = rx_packets
+
+class sampling_rate(bsn_tlv):
+    type = 30
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = sampling_rate()
+        _type = reader.read("!H")[0]
+        assert(_type == 30)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("sampling_rate {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[30] = sampling_rate
+
+class set_loopback_mode(bsn_tlv):
+    type = 74
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_loopback_mode()
+        _type = reader.read("!H")[0]
+        assert(_type == 74)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_loopback_mode {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[74] = set_loopback_mode
+
+class strip_mpls_l2_on_ingress(bsn_tlv):
+    type = 75
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = strip_mpls_l2_on_ingress()
+        _type = reader.read("!H")[0]
+        assert(_type == 75)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("strip_mpls_l2_on_ingress {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[75] = strip_mpls_l2_on_ingress
+
+class strip_mpls_l3_on_ingress(bsn_tlv):
+    type = 76
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = strip_mpls_l3_on_ingress()
+        _type = reader.read("!H")[0]
+        assert(_type == 76)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("strip_mpls_l3_on_ingress {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[76] = strip_mpls_l3_on_ingress
+
+class strip_vlan_on_egress(bsn_tlv):
+    type = 73
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = strip_vlan_on_egress()
+        _type = reader.read("!H")[0]
+        assert(_type == 73)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("strip_vlan_on_egress {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[73] = strip_vlan_on_egress
+
+class sub_agent_id(bsn_tlv):
+    type = 38
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = sub_agent_id()
+        _type = reader.read("!H")[0]
+        assert(_type == 38)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("sub_agent_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[38] = sub_agent_id
+
+class tcp_dst(bsn_tlv):
+    type = 66
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = tcp_dst()
+        _type = reader.read("!H")[0]
+        assert(_type == 66)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("tcp_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[66] = tcp_dst
+
+class tcp_src(bsn_tlv):
+    type = 65
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = tcp_src()
+        _type = reader.read("!H")[0]
+        assert(_type == 65)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("tcp_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[65] = tcp_src
+
+class tx_bytes(bsn_tlv):
+    type = 39
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!Q", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = tx_bytes()
+        _type = reader.read("!H")[0]
+        assert(_type == 39)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("tx_bytes {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[39] = tx_bytes
+
+class tx_packets(bsn_tlv):
+    type = 3
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!Q", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = tx_packets()
+        _type = reader.read("!H")[0]
+        assert(_type == 3)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("tx_packets {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[3] = tx_packets
+
+class udf_anchor(bsn_tlv):
+    type = 16
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = udf_anchor()
+        _type = reader.read("!H")[0]
+        assert(_type == 16)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("udf_anchor {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[16] = udf_anchor
+
+class udf_id(bsn_tlv):
+    type = 15
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = udf_id()
+        _type = reader.read("!H")[0]
+        assert(_type == 15)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("udf_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[15] = udf_id
+
+class udf_length(bsn_tlv):
+    type = 18
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = udf_length()
+        _type = reader.read("!H")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("udf_length {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[18] = udf_length
+
+class udf_offset(bsn_tlv):
+    type = 17
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = udf_offset()
+        _type = reader.read("!H")[0]
+        assert(_type == 17)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("udf_offset {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[17] = udf_offset
+
+class udp_dst(bsn_tlv):
+    type = 37
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = udp_dst()
+        _type = reader.read("!H")[0]
+        assert(_type == 37)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("udp_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[37] = udp_dst
+
+class udp_src(bsn_tlv):
+    type = 36
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = udp_src()
+        _type = reader.read("!H")[0]
+        assert(_type == 36)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("udp_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[36] = udp_src
+
+class unicast_query_timeout(bsn_tlv):
+    type = 9
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = unicast_query_timeout()
+        _type = reader.read("!H")[0]
+        assert(_type == 9)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("unicast_query_timeout {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[9] = unicast_query_timeout
+
+class vlan_pcp(bsn_tlv):
+    type = 72
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!B", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = vlan_pcp()
+        _type = reader.read("!H")[0]
+        assert(_type == 72)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("vlan_pcp {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[72] = vlan_pcp
+
+class vlan_vid(bsn_tlv):
+    type = 6
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = vlan_vid()
+        _type = reader.read("!H")[0]
+        assert(_type == 6)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("vlan_vid {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[6] = vlan_vid
+
+class vlan_vid_mask(bsn_tlv):
+    type = 77
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = vlan_vid_mask()
+        _type = reader.read("!H")[0]
+        assert(_type == 77)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("vlan_vid_mask {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[77] = vlan_vid_mask
+
+class vrf(bsn_tlv):
+    type = 19
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = vrf()
+        _type = reader.read("!H")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("vrf {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[19] = vrf
+
+
diff --git a/Fabric/Utilities/src/python/loxi/of13/common.py b/Fabric/Utilities/src/python/loxi/of13/common.py
new file mode 100644
index 0000000..f5c06a4
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of13/common.py
@@ -0,0 +1,4066 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of13']
+
+class bsn_controller_connection(loxi.OFObject):
+
+    def __init__(self, state=None, auxiliary_id=None, role=None, uri=None):
+        if state != None:
+            self.state = state
+        else:
+            self.state = 0
+        if auxiliary_id != None:
+            self.auxiliary_id = auxiliary_id
+        else:
+            self.auxiliary_id = 0
+        if role != None:
+            self.role = role
+        else:
+            self.role = 0
+        if uri != None:
+            self.uri = uri
+        else:
+            self.uri = ""
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.state))
+        packed.append(struct.pack("!B", self.auxiliary_id))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!L", self.role))
+        packed.append(struct.pack("!256s", self.uri))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_controller_connection()
+        obj.state = reader.read("!B")[0]
+        obj.auxiliary_id = reader.read("!B")[0]
+        reader.skip(2)
+        obj.role = reader.read("!L")[0]
+        obj.uri = reader.read("!256s")[0].rstrip("\x00")
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.state != other.state: return False
+        if self.auxiliary_id != other.auxiliary_id: return False
+        if self.role != other.role: return False
+        if self.uri != other.uri: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_controller_connection {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("state = ");
+                q.text("%#x" % self.state)
+                q.text(","); q.breakable()
+                q.text("auxiliary_id = ");
+                q.text("%#x" % self.auxiliary_id)
+                q.text(","); q.breakable()
+                q.text("role = ");
+                q.text("%#x" % self.role)
+                q.text(","); q.breakable()
+                q.text("uri = ");
+                q.pp(self.uri)
+            q.breakable()
+        q.text('}')
+
+
+class bsn_debug_counter_desc_stats_entry(loxi.OFObject):
+
+    def __init__(self, counter_id=None, name=None, description=None):
+        if counter_id != None:
+            self.counter_id = counter_id
+        else:
+            self.counter_id = 0
+        if name != None:
+            self.name = name
+        else:
+            self.name = ""
+        if description != None:
+            self.description = description
+        else:
+            self.description = ""
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!Q", self.counter_id))
+        packed.append(struct.pack("!64s", self.name))
+        packed.append(struct.pack("!256s", self.description))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_debug_counter_desc_stats_entry()
+        obj.counter_id = reader.read("!Q")[0]
+        obj.name = reader.read("!64s")[0].rstrip("\x00")
+        obj.description = reader.read("!256s")[0].rstrip("\x00")
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.counter_id != other.counter_id: return False
+        if self.name != other.name: return False
+        if self.description != other.description: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_debug_counter_desc_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("counter_id = ");
+                q.text("%#x" % self.counter_id)
+                q.text(","); q.breakable()
+                q.text("name = ");
+                q.pp(self.name)
+                q.text(","); q.breakable()
+                q.text("description = ");
+                q.pp(self.description)
+            q.breakable()
+        q.text('}')
+
+
+class bsn_debug_counter_stats_entry(loxi.OFObject):
+
+    def __init__(self, counter_id=None, value=None):
+        if counter_id != None:
+            self.counter_id = counter_id
+        else:
+            self.counter_id = 0
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!Q", self.counter_id))
+        packed.append(struct.pack("!Q", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_debug_counter_stats_entry()
+        obj.counter_id = reader.read("!Q")[0]
+        obj.value = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.counter_id != other.counter_id: return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_debug_counter_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("counter_id = ");
+                q.text("%#x" % self.counter_id)
+                q.text(","); q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+
+class bsn_flow_checksum_bucket_stats_entry(loxi.OFObject):
+
+    def __init__(self, checksum=None):
+        if checksum != None:
+            self.checksum = checksum
+        else:
+            self.checksum = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!Q", self.checksum))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_flow_checksum_bucket_stats_entry()
+        obj.checksum = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.checksum != other.checksum: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_flow_checksum_bucket_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("checksum = ");
+                q.text("%#x" % self.checksum)
+            q.breakable()
+        q.text('}')
+
+
+class bsn_generic_stats_entry(loxi.OFObject):
+
+    def __init__(self, tlvs=None):
+        if tlvs != None:
+            self.tlvs = tlvs
+        else:
+            self.tlvs = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 0
+        packed.append(loxi.generic_util.pack_list(self.tlvs))
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_generic_stats_entry()
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 2)
+        obj.tlvs = loxi.generic_util.unpack_list(reader, ofp.bsn_tlv.bsn_tlv.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.tlvs != other.tlvs: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_generic_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("tlvs = ");
+                q.pp(self.tlvs)
+            q.breakable()
+        q.text('}')
+
+
+class bsn_gentable_bucket_stats_entry(loxi.OFObject):
+
+    def __init__(self, checksum=None):
+        if checksum != None:
+            self.checksum = checksum
+        else:
+            self.checksum = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(util.pack_checksum_128(self.checksum))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_bucket_stats_entry()
+        obj.checksum = util.unpack_checksum_128(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.checksum != other.checksum: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_bucket_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("checksum = ");
+                q.pp(self.checksum)
+            q.breakable()
+        q.text('}')
+
+
+class bsn_gentable_desc_stats_entry(loxi.OFObject):
+
+    def __init__(self, table_id=None, name=None, buckets_size=None, max_entries=None):
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if name != None:
+            self.name = name
+        else:
+            self.name = ""
+        if buckets_size != None:
+            self.buckets_size = buckets_size
+        else:
+            self.buckets_size = 0
+        if max_entries != None:
+            self.max_entries = max_entries
+        else:
+            self.max_entries = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 0
+        packed.append(struct.pack("!H", self.table_id))
+        packed.append(struct.pack("!32s", self.name))
+        packed.append(struct.pack("!L", self.buckets_size))
+        packed.append(struct.pack("!L", self.max_entries))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_desc_stats_entry()
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 2)
+        obj.table_id = reader.read("!H")[0]
+        obj.name = reader.read("!32s")[0].rstrip("\x00")
+        obj.buckets_size = reader.read("!L")[0]
+        obj.max_entries = reader.read("!L")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.table_id != other.table_id: return False
+        if self.name != other.name: return False
+        if self.buckets_size != other.buckets_size: return False
+        if self.max_entries != other.max_entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_desc_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("name = ");
+                q.pp(self.name)
+                q.text(","); q.breakable()
+                q.text("buckets_size = ");
+                q.text("%#x" % self.buckets_size)
+                q.text(","); q.breakable()
+                q.text("max_entries = ");
+                q.text("%#x" % self.max_entries)
+            q.breakable()
+        q.text('}')
+
+
+class bsn_gentable_entry_desc_stats_entry(loxi.OFObject):
+
+    def __init__(self, checksum=None, key=None, value=None):
+        if checksum != None:
+            self.checksum = checksum
+        else:
+            self.checksum = 0
+        if key != None:
+            self.key = key
+        else:
+            self.key = []
+        if value != None:
+            self.value = value
+        else:
+            self.value = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 0
+        packed.append(struct.pack("!H", 0)) # placeholder for key_length at index 1
+        packed.append(util.pack_checksum_128(self.checksum))
+        packed.append(loxi.generic_util.pack_list(self.key))
+        packed[1] = struct.pack("!H", len(packed[-1]))
+        packed.append(loxi.generic_util.pack_list(self.value))
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_entry_desc_stats_entry()
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 2)
+        _key_length = reader.read("!H")[0]
+        obj.checksum = util.unpack_checksum_128(reader)
+        obj.key = loxi.generic_util.unpack_list(reader.slice(_key_length), ofp.bsn_tlv.bsn_tlv.unpack)
+        obj.value = loxi.generic_util.unpack_list(reader, ofp.bsn_tlv.bsn_tlv.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.checksum != other.checksum: return False
+        if self.key != other.key: return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_entry_desc_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("checksum = ");
+                q.pp(self.checksum)
+                q.text(","); q.breakable()
+                q.text("key = ");
+                q.pp(self.key)
+                q.text(","); q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+            q.breakable()
+        q.text('}')
+
+
+class bsn_gentable_entry_stats_entry(loxi.OFObject):
+
+    def __init__(self, key=None, stats=None):
+        if key != None:
+            self.key = key
+        else:
+            self.key = []
+        if stats != None:
+            self.stats = stats
+        else:
+            self.stats = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 0
+        packed.append(struct.pack("!H", 0)) # placeholder for key_length at index 1
+        packed.append(loxi.generic_util.pack_list(self.key))
+        packed[1] = struct.pack("!H", len(packed[-1]))
+        packed.append(loxi.generic_util.pack_list(self.stats))
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_entry_stats_entry()
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 2)
+        _key_length = reader.read("!H")[0]
+        obj.key = loxi.generic_util.unpack_list(reader.slice(_key_length), ofp.bsn_tlv.bsn_tlv.unpack)
+        obj.stats = loxi.generic_util.unpack_list(reader, ofp.bsn_tlv.bsn_tlv.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.key != other.key: return False
+        if self.stats != other.stats: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_entry_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("key = ");
+                q.pp(self.key)
+                q.text(","); q.breakable()
+                q.text("stats = ");
+                q.pp(self.stats)
+            q.breakable()
+        q.text('}')
+
+
+class bsn_gentable_stats_entry(loxi.OFObject):
+
+    def __init__(self, table_id=None, entry_count=None, checksum=None):
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if entry_count != None:
+            self.entry_count = entry_count
+        else:
+            self.entry_count = 0
+        if checksum != None:
+            self.checksum = checksum
+        else:
+            self.checksum = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.table_id))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!L", self.entry_count))
+        packed.append(util.pack_checksum_128(self.checksum))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_stats_entry()
+        obj.table_id = reader.read("!H")[0]
+        reader.skip(2)
+        obj.entry_count = reader.read("!L")[0]
+        obj.checksum = util.unpack_checksum_128(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.table_id != other.table_id: return False
+        if self.entry_count != other.entry_count: return False
+        if self.checksum != other.checksum: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("entry_count = ");
+                q.text("%#x" % self.entry_count)
+                q.text(","); q.breakable()
+                q.text("checksum = ");
+                q.pp(self.checksum)
+            q.breakable()
+        q.text('}')
+
+
+class bsn_interface(loxi.OFObject):
+
+    def __init__(self, hw_addr=None, name=None, ipv4_addr=None, ipv4_netmask=None):
+        if hw_addr != None:
+            self.hw_addr = hw_addr
+        else:
+            self.hw_addr = [0,0,0,0,0,0]
+        if name != None:
+            self.name = name
+        else:
+            self.name = ""
+        if ipv4_addr != None:
+            self.ipv4_addr = ipv4_addr
+        else:
+            self.ipv4_addr = 0
+        if ipv4_netmask != None:
+            self.ipv4_netmask = ipv4_netmask
+        else:
+            self.ipv4_netmask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!6B", *self.hw_addr))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!16s", self.name))
+        packed.append(struct.pack("!L", self.ipv4_addr))
+        packed.append(struct.pack("!L", self.ipv4_netmask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_interface()
+        obj.hw_addr = list(reader.read('!6B'))
+        reader.skip(2)
+        obj.name = reader.read("!16s")[0].rstrip("\x00")
+        obj.ipv4_addr = reader.read("!L")[0]
+        obj.ipv4_netmask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.hw_addr != other.hw_addr: return False
+        if self.name != other.name: return False
+        if self.ipv4_addr != other.ipv4_addr: return False
+        if self.ipv4_netmask != other.ipv4_netmask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_interface {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("hw_addr = ");
+                q.text(util.pretty_mac(self.hw_addr))
+                q.text(","); q.breakable()
+                q.text("name = ");
+                q.pp(self.name)
+                q.text(","); q.breakable()
+                q.text("ipv4_addr = ");
+                q.text(util.pretty_ipv4(self.ipv4_addr))
+                q.text(","); q.breakable()
+                q.text("ipv4_netmask = ");
+                q.text(util.pretty_ipv4(self.ipv4_netmask))
+            q.breakable()
+        q.text('}')
+
+
+class bsn_lacp_stats_entry(loxi.OFObject):
+
+    def __init__(self, port_no=None, actor_sys_priority=None, actor_sys_mac=None, actor_port_priority=None, actor_port_num=None, actor_key=None, convergence_status=None, partner_sys_priority=None, partner_sys_mac=None, partner_port_priority=None, partner_port_num=None, partner_key=None):
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if actor_sys_priority != None:
+            self.actor_sys_priority = actor_sys_priority
+        else:
+            self.actor_sys_priority = 0
+        if actor_sys_mac != None:
+            self.actor_sys_mac = actor_sys_mac
+        else:
+            self.actor_sys_mac = [0,0,0,0,0,0]
+        if actor_port_priority != None:
+            self.actor_port_priority = actor_port_priority
+        else:
+            self.actor_port_priority = 0
+        if actor_port_num != None:
+            self.actor_port_num = actor_port_num
+        else:
+            self.actor_port_num = 0
+        if actor_key != None:
+            self.actor_key = actor_key
+        else:
+            self.actor_key = 0
+        if convergence_status != None:
+            self.convergence_status = convergence_status
+        else:
+            self.convergence_status = 0
+        if partner_sys_priority != None:
+            self.partner_sys_priority = partner_sys_priority
+        else:
+            self.partner_sys_priority = 0
+        if partner_sys_mac != None:
+            self.partner_sys_mac = partner_sys_mac
+        else:
+            self.partner_sys_mac = [0,0,0,0,0,0]
+        if partner_port_priority != None:
+            self.partner_port_priority = partner_port_priority
+        else:
+            self.partner_port_priority = 0
+        if partner_port_num != None:
+            self.partner_port_num = partner_port_num
+        else:
+            self.partner_port_num = 0
+        if partner_key != None:
+            self.partner_key = partner_key
+        else:
+            self.partner_key = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!H", self.actor_sys_priority))
+        packed.append(struct.pack("!6B", *self.actor_sys_mac))
+        packed.append(struct.pack("!H", self.actor_port_priority))
+        packed.append(struct.pack("!H", self.actor_port_num))
+        packed.append(struct.pack("!H", self.actor_key))
+        packed.append(struct.pack("!B", self.convergence_status))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!H", self.partner_sys_priority))
+        packed.append(struct.pack("!6B", *self.partner_sys_mac))
+        packed.append(struct.pack("!H", self.partner_port_priority))
+        packed.append(struct.pack("!H", self.partner_port_num))
+        packed.append(struct.pack("!H", self.partner_key))
+        packed.append('\x00' * 2)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_lacp_stats_entry()
+        obj.port_no = util.unpack_port_no(reader)
+        obj.actor_sys_priority = reader.read("!H")[0]
+        obj.actor_sys_mac = list(reader.read('!6B'))
+        obj.actor_port_priority = reader.read("!H")[0]
+        obj.actor_port_num = reader.read("!H")[0]
+        obj.actor_key = reader.read("!H")[0]
+        obj.convergence_status = reader.read("!B")[0]
+        reader.skip(1)
+        obj.partner_sys_priority = reader.read("!H")[0]
+        obj.partner_sys_mac = list(reader.read('!6B'))
+        obj.partner_port_priority = reader.read("!H")[0]
+        obj.partner_port_num = reader.read("!H")[0]
+        obj.partner_key = reader.read("!H")[0]
+        reader.skip(2)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.port_no != other.port_no: return False
+        if self.actor_sys_priority != other.actor_sys_priority: return False
+        if self.actor_sys_mac != other.actor_sys_mac: return False
+        if self.actor_port_priority != other.actor_port_priority: return False
+        if self.actor_port_num != other.actor_port_num: return False
+        if self.actor_key != other.actor_key: return False
+        if self.convergence_status != other.convergence_status: return False
+        if self.partner_sys_priority != other.partner_sys_priority: return False
+        if self.partner_sys_mac != other.partner_sys_mac: return False
+        if self.partner_port_priority != other.partner_port_priority: return False
+        if self.partner_port_num != other.partner_port_num: return False
+        if self.partner_key != other.partner_key: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_lacp_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("actor_sys_priority = ");
+                q.text("%#x" % self.actor_sys_priority)
+                q.text(","); q.breakable()
+                q.text("actor_sys_mac = ");
+                q.text(util.pretty_mac(self.actor_sys_mac))
+                q.text(","); q.breakable()
+                q.text("actor_port_priority = ");
+                q.text("%#x" % self.actor_port_priority)
+                q.text(","); q.breakable()
+                q.text("actor_port_num = ");
+                q.text("%#x" % self.actor_port_num)
+                q.text(","); q.breakable()
+                q.text("actor_key = ");
+                q.text("%#x" % self.actor_key)
+                q.text(","); q.breakable()
+                q.text("convergence_status = ");
+                q.text("%#x" % self.convergence_status)
+                q.text(","); q.breakable()
+                q.text("partner_sys_priority = ");
+                q.text("%#x" % self.partner_sys_priority)
+                q.text(","); q.breakable()
+                q.text("partner_sys_mac = ");
+                q.text(util.pretty_mac(self.partner_sys_mac))
+                q.text(","); q.breakable()
+                q.text("partner_port_priority = ");
+                q.text("%#x" % self.partner_port_priority)
+                q.text(","); q.breakable()
+                q.text("partner_port_num = ");
+                q.text("%#x" % self.partner_port_num)
+                q.text(","); q.breakable()
+                q.text("partner_key = ");
+                q.text("%#x" % self.partner_key)
+            q.breakable()
+        q.text('}')
+
+
+class bsn_port_counter_stats_entry(loxi.OFObject):
+
+    def __init__(self, port_no=None, values=None):
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if values != None:
+            self.values = values
+        else:
+            self.values = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 0
+        packed.append('\x00' * 2)
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(loxi.generic_util.pack_list(self.values))
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_port_counter_stats_entry()
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 2)
+        reader.skip(2)
+        obj.port_no = util.unpack_port_no(reader)
+        obj.values = loxi.generic_util.unpack_list(reader, ofp.common.uint64.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.port_no != other.port_no: return False
+        if self.values != other.values: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_port_counter_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("values = ");
+                q.pp(self.values)
+            q.breakable()
+        q.text('}')
+
+
+class bsn_switch_pipeline_stats_entry(loxi.OFObject):
+
+    def __init__(self, pipeline=None):
+        if pipeline != None:
+            self.pipeline = pipeline
+        else:
+            self.pipeline = ""
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!256s", self.pipeline))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_switch_pipeline_stats_entry()
+        obj.pipeline = reader.read("!256s")[0].rstrip("\x00")
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.pipeline != other.pipeline: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_switch_pipeline_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("pipeline = ");
+                q.pp(self.pipeline)
+            q.breakable()
+        q.text('}')
+
+
+class bsn_table_checksum_stats_entry(loxi.OFObject):
+
+    def __init__(self, table_id=None, checksum=None):
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if checksum != None:
+            self.checksum = checksum
+        else:
+            self.checksum = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append(struct.pack("!Q", self.checksum))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_table_checksum_stats_entry()
+        obj.table_id = reader.read("!B")[0]
+        obj.checksum = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.table_id != other.table_id: return False
+        if self.checksum != other.checksum: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_table_checksum_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("checksum = ");
+                q.text("%#x" % self.checksum)
+            q.breakable()
+        q.text('}')
+
+
+class bsn_vport(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = bsn_vport.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = bsn_vport()
+        obj.type = reader.read("!H")[0]
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vport {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class bsn_vlan_counter_stats_entry(loxi.OFObject):
+
+    def __init__(self, vlan_vid=None, values=None):
+        if vlan_vid != None:
+            self.vlan_vid = vlan_vid
+        else:
+            self.vlan_vid = 0
+        if values != None:
+            self.values = values
+        else:
+            self.values = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 0
+        packed.append(struct.pack("!H", self.vlan_vid))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.values))
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vlan_counter_stats_entry()
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 2)
+        obj.vlan_vid = reader.read("!H")[0]
+        reader.skip(4)
+        obj.values = loxi.generic_util.unpack_list(reader, ofp.common.uint64.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.vlan_vid != other.vlan_vid: return False
+        if self.values != other.values: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vlan_counter_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("vlan_vid = ");
+                q.text("%#x" % self.vlan_vid)
+                q.text(","); q.breakable()
+                q.text("values = ");
+                q.pp(self.values)
+            q.breakable()
+        q.text('}')
+
+
+class bsn_vport_l2gre(bsn_vport):
+    type = 1
+
+    def __init__(self, flags=None, port_no=None, loopback_port_no=None, local_mac=None, nh_mac=None, src_ip=None, dst_ip=None, dscp=None, ttl=None, vpn=None, rate_limit=None, if_name=None):
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if loopback_port_no != None:
+            self.loopback_port_no = loopback_port_no
+        else:
+            self.loopback_port_no = 0
+        if local_mac != None:
+            self.local_mac = local_mac
+        else:
+            self.local_mac = [0,0,0,0,0,0]
+        if nh_mac != None:
+            self.nh_mac = nh_mac
+        else:
+            self.nh_mac = [0,0,0,0,0,0]
+        if src_ip != None:
+            self.src_ip = src_ip
+        else:
+            self.src_ip = 0
+        if dst_ip != None:
+            self.dst_ip = dst_ip
+        else:
+            self.dst_ip = 0
+        if dscp != None:
+            self.dscp = dscp
+        else:
+            self.dscp = 0
+        if ttl != None:
+            self.ttl = ttl
+        else:
+            self.ttl = 0
+        if vpn != None:
+            self.vpn = vpn
+        else:
+            self.vpn = 0
+        if rate_limit != None:
+            self.rate_limit = rate_limit
+        else:
+            self.rate_limit = 0
+        if if_name != None:
+            self.if_name = if_name
+        else:
+            self.if_name = ""
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.flags))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(util.pack_port_no(self.loopback_port_no))
+        packed.append(struct.pack("!6B", *self.local_mac))
+        packed.append(struct.pack("!6B", *self.nh_mac))
+        packed.append(struct.pack("!L", self.src_ip))
+        packed.append(struct.pack("!L", self.dst_ip))
+        packed.append(struct.pack("!B", self.dscp))
+        packed.append(struct.pack("!B", self.ttl))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!L", self.vpn))
+        packed.append(struct.pack("!L", self.rate_limit))
+        packed.append(struct.pack("!16s", self.if_name))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vport_l2gre()
+        _type = reader.read("!H")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.flags = reader.read("!L")[0]
+        obj.port_no = util.unpack_port_no(reader)
+        obj.loopback_port_no = util.unpack_port_no(reader)
+        obj.local_mac = list(reader.read('!6B'))
+        obj.nh_mac = list(reader.read('!6B'))
+        obj.src_ip = reader.read("!L")[0]
+        obj.dst_ip = reader.read("!L")[0]
+        obj.dscp = reader.read("!B")[0]
+        obj.ttl = reader.read("!B")[0]
+        reader.skip(2)
+        obj.vpn = reader.read("!L")[0]
+        obj.rate_limit = reader.read("!L")[0]
+        obj.if_name = reader.read("!16s")[0].rstrip("\x00")
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.flags != other.flags: return False
+        if self.port_no != other.port_no: return False
+        if self.loopback_port_no != other.loopback_port_no: return False
+        if self.local_mac != other.local_mac: return False
+        if self.nh_mac != other.nh_mac: return False
+        if self.src_ip != other.src_ip: return False
+        if self.dst_ip != other.dst_ip: return False
+        if self.dscp != other.dscp: return False
+        if self.ttl != other.ttl: return False
+        if self.vpn != other.vpn: return False
+        if self.rate_limit != other.rate_limit: return False
+        if self.if_name != other.if_name: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vport_l2gre {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("loopback_port_no = ");
+                q.text(util.pretty_port(self.loopback_port_no))
+                q.text(","); q.breakable()
+                q.text("local_mac = ");
+                q.text(util.pretty_mac(self.local_mac))
+                q.text(","); q.breakable()
+                q.text("nh_mac = ");
+                q.text(util.pretty_mac(self.nh_mac))
+                q.text(","); q.breakable()
+                q.text("src_ip = ");
+                q.text(util.pretty_ipv4(self.src_ip))
+                q.text(","); q.breakable()
+                q.text("dst_ip = ");
+                q.text(util.pretty_ipv4(self.dst_ip))
+                q.text(","); q.breakable()
+                q.text("dscp = ");
+                q.text("%#x" % self.dscp)
+                q.text(","); q.breakable()
+                q.text("ttl = ");
+                q.text("%#x" % self.ttl)
+                q.text(","); q.breakable()
+                q.text("vpn = ");
+                q.text("%#x" % self.vpn)
+                q.text(","); q.breakable()
+                q.text("rate_limit = ");
+                q.text("%#x" % self.rate_limit)
+                q.text(","); q.breakable()
+                q.text("if_name = ");
+                q.pp(self.if_name)
+            q.breakable()
+        q.text('}')
+
+bsn_vport.subtypes[1] = bsn_vport_l2gre
+
+class bsn_vport_q_in_q(bsn_vport):
+    type = 0
+
+    def __init__(self, port_no=None, ingress_tpid=None, ingress_vlan_id=None, egress_tpid=None, egress_vlan_id=None, if_name=None):
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if ingress_tpid != None:
+            self.ingress_tpid = ingress_tpid
+        else:
+            self.ingress_tpid = 0
+        if ingress_vlan_id != None:
+            self.ingress_vlan_id = ingress_vlan_id
+        else:
+            self.ingress_vlan_id = 0
+        if egress_tpid != None:
+            self.egress_tpid = egress_tpid
+        else:
+            self.egress_tpid = 0
+        if egress_vlan_id != None:
+            self.egress_vlan_id = egress_vlan_id
+        else:
+            self.egress_vlan_id = 0
+        if if_name != None:
+            self.if_name = if_name
+        else:
+            self.if_name = ""
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.port_no))
+        packed.append(struct.pack("!H", self.ingress_tpid))
+        packed.append(struct.pack("!H", self.ingress_vlan_id))
+        packed.append(struct.pack("!H", self.egress_tpid))
+        packed.append(struct.pack("!H", self.egress_vlan_id))
+        packed.append(struct.pack("!16s", self.if_name))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vport_q_in_q()
+        _type = reader.read("!H")[0]
+        assert(_type == 0)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.port_no = reader.read("!L")[0]
+        obj.ingress_tpid = reader.read("!H")[0]
+        obj.ingress_vlan_id = reader.read("!H")[0]
+        obj.egress_tpid = reader.read("!H")[0]
+        obj.egress_vlan_id = reader.read("!H")[0]
+        obj.if_name = reader.read("!16s")[0].rstrip("\x00")
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.port_no != other.port_no: return False
+        if self.ingress_tpid != other.ingress_tpid: return False
+        if self.ingress_vlan_id != other.ingress_vlan_id: return False
+        if self.egress_tpid != other.egress_tpid: return False
+        if self.egress_vlan_id != other.egress_vlan_id: return False
+        if self.if_name != other.if_name: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vport_q_in_q {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("port_no = ");
+                q.text("%#x" % self.port_no)
+                q.text(","); q.breakable()
+                q.text("ingress_tpid = ");
+                q.text("%#x" % self.ingress_tpid)
+                q.text(","); q.breakable()
+                q.text("ingress_vlan_id = ");
+                q.text("%#x" % self.ingress_vlan_id)
+                q.text(","); q.breakable()
+                q.text("egress_tpid = ");
+                q.text("%#x" % self.egress_tpid)
+                q.text(","); q.breakable()
+                q.text("egress_vlan_id = ");
+                q.text("%#x" % self.egress_vlan_id)
+                q.text(","); q.breakable()
+                q.text("if_name = ");
+                q.pp(self.if_name)
+            q.breakable()
+        q.text('}')
+
+bsn_vport.subtypes[0] = bsn_vport_q_in_q
+
+class bsn_vrf_counter_stats_entry(loxi.OFObject):
+
+    def __init__(self, vrf=None, values=None):
+        if vrf != None:
+            self.vrf = vrf
+        else:
+            self.vrf = 0
+        if values != None:
+            self.values = values
+        else:
+            self.values = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 0
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!L", self.vrf))
+        packed.append(loxi.generic_util.pack_list(self.values))
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vrf_counter_stats_entry()
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 2)
+        reader.skip(2)
+        obj.vrf = reader.read("!L")[0]
+        obj.values = loxi.generic_util.unpack_list(reader, ofp.common.uint64.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.vrf != other.vrf: return False
+        if self.values != other.values: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vrf_counter_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("vrf = ");
+                q.text("%#x" % self.vrf)
+                q.text(","); q.breakable()
+                q.text("values = ");
+                q.pp(self.values)
+            q.breakable()
+        q.text('}')
+
+
+class bucket(loxi.OFObject):
+
+    def __init__(self, weight=None, watch_port=None, watch_group=None, actions=None):
+        if weight != None:
+            self.weight = weight
+        else:
+            self.weight = 0
+        if watch_port != None:
+            self.watch_port = watch_port
+        else:
+            self.watch_port = 0
+        if watch_group != None:
+            self.watch_group = watch_group
+        else:
+            self.watch_group = 0
+        if actions != None:
+            self.actions = actions
+        else:
+            self.actions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 0
+        packed.append(struct.pack("!H", self.weight))
+        packed.append(util.pack_port_no(self.watch_port))
+        packed.append(struct.pack("!L", self.watch_group))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.actions))
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bucket()
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 2)
+        obj.weight = reader.read("!H")[0]
+        obj.watch_port = util.unpack_port_no(reader)
+        obj.watch_group = reader.read("!L")[0]
+        reader.skip(4)
+        obj.actions = loxi.generic_util.unpack_list(reader, ofp.action.action.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.weight != other.weight: return False
+        if self.watch_port != other.watch_port: return False
+        if self.watch_group != other.watch_group: return False
+        if self.actions != other.actions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bucket {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("weight = ");
+                q.text("%#x" % self.weight)
+                q.text(","); q.breakable()
+                q.text("watch_port = ");
+                q.text(util.pretty_port(self.watch_port))
+                q.text(","); q.breakable()
+                q.text("watch_group = ");
+                q.text("%#x" % self.watch_group)
+                q.text(","); q.breakable()
+                q.text("actions = ");
+                q.pp(self.actions)
+            q.breakable()
+        q.text('}')
+
+
+class bucket_counter(loxi.OFObject):
+
+    def __init__(self, packet_count=None, byte_count=None):
+        if packet_count != None:
+            self.packet_count = packet_count
+        else:
+            self.packet_count = 0
+        if byte_count != None:
+            self.byte_count = byte_count
+        else:
+            self.byte_count = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!Q", self.packet_count))
+        packed.append(struct.pack("!Q", self.byte_count))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bucket_counter()
+        obj.packet_count = reader.read("!Q")[0]
+        obj.byte_count = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.packet_count != other.packet_count: return False
+        if self.byte_count != other.byte_count: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bucket_counter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("packet_count = ");
+                q.text("%#x" % self.packet_count)
+                q.text(","); q.breakable()
+                q.text("byte_count = ");
+                q.text("%#x" % self.byte_count)
+            q.breakable()
+        q.text('}')
+
+
+class flow_stats_entry(loxi.OFObject):
+
+    def __init__(self, table_id=None, duration_sec=None, duration_nsec=None, priority=None, idle_timeout=None, hard_timeout=None, flags=None, cookie=None, packet_count=None, byte_count=None, match=None, instructions=None):
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if duration_sec != None:
+            self.duration_sec = duration_sec
+        else:
+            self.duration_sec = 0
+        if duration_nsec != None:
+            self.duration_nsec = duration_nsec
+        else:
+            self.duration_nsec = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if packet_count != None:
+            self.packet_count = packet_count
+        else:
+            self.packet_count = 0
+        if byte_count != None:
+            self.byte_count = byte_count
+        else:
+            self.byte_count = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if instructions != None:
+            self.instructions = instructions
+        else:
+            self.instructions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 0
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!L", self.duration_sec))
+        packed.append(struct.pack("!L", self.duration_nsec))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.packet_count))
+        packed.append(struct.pack("!Q", self.byte_count))
+        packed.append(self.match.pack())
+        packed.append(loxi.generic_util.pack_list(self.instructions))
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_stats_entry()
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 2)
+        obj.table_id = reader.read("!B")[0]
+        reader.skip(1)
+        obj.duration_sec = reader.read("!L")[0]
+        obj.duration_nsec = reader.read("!L")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.cookie = reader.read("!Q")[0]
+        obj.packet_count = reader.read("!Q")[0]
+        obj.byte_count = reader.read("!Q")[0]
+        obj.match = ofp.match.unpack(reader)
+        obj.instructions = loxi.generic_util.unpack_list(reader, ofp.instruction.instruction.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.table_id != other.table_id: return False
+        if self.duration_sec != other.duration_sec: return False
+        if self.duration_nsec != other.duration_nsec: return False
+        if self.priority != other.priority: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.flags != other.flags: return False
+        if self.cookie != other.cookie: return False
+        if self.packet_count != other.packet_count: return False
+        if self.byte_count != other.byte_count: return False
+        if self.match != other.match: return False
+        if self.instructions != other.instructions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("duration_sec = ");
+                q.text("%#x" % self.duration_sec)
+                q.text(","); q.breakable()
+                q.text("duration_nsec = ");
+                q.text("%#x" % self.duration_nsec)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("packet_count = ");
+                q.text("%#x" % self.packet_count)
+                q.text(","); q.breakable()
+                q.text("byte_count = ");
+                q.text("%#x" % self.byte_count)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("instructions = ");
+                q.pp(self.instructions)
+            q.breakable()
+        q.text('}')
+
+
+class group_desc_stats_entry(loxi.OFObject):
+
+    def __init__(self, group_type=None, group_id=None, buckets=None):
+        if group_type != None:
+            self.group_type = group_type
+        else:
+            self.group_type = 0
+        if group_id != None:
+            self.group_id = group_id
+        else:
+            self.group_id = 0
+        if buckets != None:
+            self.buckets = buckets
+        else:
+            self.buckets = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 0
+        packed.append(struct.pack("!B", self.group_type))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!L", self.group_id))
+        packed.append(loxi.generic_util.pack_list(self.buckets))
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_desc_stats_entry()
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 2)
+        obj.group_type = reader.read("!B")[0]
+        reader.skip(1)
+        obj.group_id = reader.read("!L")[0]
+        obj.buckets = loxi.generic_util.unpack_list(reader, ofp.common.bucket.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.group_type != other.group_type: return False
+        if self.group_id != other.group_id: return False
+        if self.buckets != other.buckets: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_desc_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("group_type = ");
+                q.text("%#x" % self.group_type)
+                q.text(","); q.breakable()
+                q.text("group_id = ");
+                q.text("%#x" % self.group_id)
+                q.text(","); q.breakable()
+                q.text("buckets = ");
+                q.pp(self.buckets)
+            q.breakable()
+        q.text('}')
+
+
+class group_stats_entry(loxi.OFObject):
+
+    def __init__(self, group_id=None, ref_count=None, packet_count=None, byte_count=None, duration_sec=None, duration_nsec=None, bucket_stats=None):
+        if group_id != None:
+            self.group_id = group_id
+        else:
+            self.group_id = 0
+        if ref_count != None:
+            self.ref_count = ref_count
+        else:
+            self.ref_count = 0
+        if packet_count != None:
+            self.packet_count = packet_count
+        else:
+            self.packet_count = 0
+        if byte_count != None:
+            self.byte_count = byte_count
+        else:
+            self.byte_count = 0
+        if duration_sec != None:
+            self.duration_sec = duration_sec
+        else:
+            self.duration_sec = 0
+        if duration_nsec != None:
+            self.duration_nsec = duration_nsec
+        else:
+            self.duration_nsec = 0
+        if bucket_stats != None:
+            self.bucket_stats = bucket_stats
+        else:
+            self.bucket_stats = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 0
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!L", self.group_id))
+        packed.append(struct.pack("!L", self.ref_count))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!Q", self.packet_count))
+        packed.append(struct.pack("!Q", self.byte_count))
+        packed.append(struct.pack("!L", self.duration_sec))
+        packed.append(struct.pack("!L", self.duration_nsec))
+        packed.append(loxi.generic_util.pack_list(self.bucket_stats))
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_stats_entry()
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 2)
+        reader.skip(2)
+        obj.group_id = reader.read("!L")[0]
+        obj.ref_count = reader.read("!L")[0]
+        reader.skip(4)
+        obj.packet_count = reader.read("!Q")[0]
+        obj.byte_count = reader.read("!Q")[0]
+        obj.duration_sec = reader.read("!L")[0]
+        obj.duration_nsec = reader.read("!L")[0]
+        obj.bucket_stats = loxi.generic_util.unpack_list(reader, ofp.common.bucket_counter.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.group_id != other.group_id: return False
+        if self.ref_count != other.ref_count: return False
+        if self.packet_count != other.packet_count: return False
+        if self.byte_count != other.byte_count: return False
+        if self.duration_sec != other.duration_sec: return False
+        if self.duration_nsec != other.duration_nsec: return False
+        if self.bucket_stats != other.bucket_stats: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("group_id = ");
+                q.text("%#x" % self.group_id)
+                q.text(","); q.breakable()
+                q.text("ref_count = ");
+                q.text("%#x" % self.ref_count)
+                q.text(","); q.breakable()
+                q.text("packet_count = ");
+                q.text("%#x" % self.packet_count)
+                q.text(","); q.breakable()
+                q.text("byte_count = ");
+                q.text("%#x" % self.byte_count)
+                q.text(","); q.breakable()
+                q.text("duration_sec = ");
+                q.text("%#x" % self.duration_sec)
+                q.text(","); q.breakable()
+                q.text("duration_nsec = ");
+                q.text("%#x" % self.duration_nsec)
+                q.text(","); q.breakable()
+                q.text("bucket_stats = ");
+                q.pp(self.bucket_stats)
+            q.breakable()
+        q.text('}')
+
+
+class hello_elem(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = hello_elem.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = hello_elem()
+        obj.type = reader.read("!H")[0]
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("hello_elem {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class hello_elem_versionbitmap(hello_elem):
+    type = 1
+
+    def __init__(self, bitmaps=None):
+        if bitmaps != None:
+            self.bitmaps = bitmaps
+        else:
+            self.bitmaps = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(loxi.generic_util.pack_list(self.bitmaps))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = hello_elem_versionbitmap()
+        _type = reader.read("!H")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.bitmaps = loxi.generic_util.unpack_list(reader, ofp.common.uint32.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.bitmaps != other.bitmaps: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("hello_elem_versionbitmap {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("bitmaps = ");
+                q.pp(self.bitmaps)
+            q.breakable()
+        q.text('}')
+
+hello_elem.subtypes[1] = hello_elem_versionbitmap
+
+class match_v3(loxi.OFObject):
+    type = 1
+
+    def __init__(self, oxm_list=None):
+        if oxm_list != None:
+            self.oxm_list = oxm_list
+        else:
+            self.oxm_list = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(loxi.generic_util.pack_list(self.oxm_list))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        packed.append(loxi.generic_util.pad_to(8, length))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = match_v3()
+        _type = reader.read("!H")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.oxm_list = loxi.generic_util.unpack_list(reader, ofp.oxm.oxm.unpack)
+        orig_reader.skip_align()
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.oxm_list != other.oxm_list: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("match_v3 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("oxm_list = ");
+                q.pp(self.oxm_list)
+            q.breakable()
+        q.text('}')
+
+
+class meter_band_stats(loxi.OFObject):
+
+    def __init__(self, packet_band_count=None, byte_band_count=None):
+        if packet_band_count != None:
+            self.packet_band_count = packet_band_count
+        else:
+            self.packet_band_count = 0
+        if byte_band_count != None:
+            self.byte_band_count = byte_band_count
+        else:
+            self.byte_band_count = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!Q", self.packet_band_count))
+        packed.append(struct.pack("!Q", self.byte_band_count))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = meter_band_stats()
+        obj.packet_band_count = reader.read("!Q")[0]
+        obj.byte_band_count = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.packet_band_count != other.packet_band_count: return False
+        if self.byte_band_count != other.byte_band_count: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("meter_band_stats {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("packet_band_count = ");
+                q.text("%#x" % self.packet_band_count)
+                q.text(","); q.breakable()
+                q.text("byte_band_count = ");
+                q.text("%#x" % self.byte_band_count)
+            q.breakable()
+        q.text('}')
+
+
+class meter_config(loxi.OFObject):
+
+    def __init__(self, flags=None, meter_id=None, entries=None):
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if meter_id != None:
+            self.meter_id = meter_id
+        else:
+            self.meter_id = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 0
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(struct.pack("!L", self.meter_id))
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = meter_config()
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 2)
+        obj.flags = reader.read("!H")[0]
+        obj.meter_id = reader.read("!L")[0]
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.meter_band.meter_band.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.flags != other.flags: return False
+        if self.meter_id != other.meter_id: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("meter_config {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("meter_id = ");
+                q.text("%#x" % self.meter_id)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+
+class meter_features(loxi.OFObject):
+
+    def __init__(self, max_meter=None, band_types=None, capabilities=None, max_bands=None, max_color=None):
+        if max_meter != None:
+            self.max_meter = max_meter
+        else:
+            self.max_meter = 0
+        if band_types != None:
+            self.band_types = band_types
+        else:
+            self.band_types = 0
+        if capabilities != None:
+            self.capabilities = capabilities
+        else:
+            self.capabilities = 0
+        if max_bands != None:
+            self.max_bands = max_bands
+        else:
+            self.max_bands = 0
+        if max_color != None:
+            self.max_color = max_color
+        else:
+            self.max_color = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.max_meter))
+        packed.append(struct.pack("!L", self.band_types))
+        packed.append(struct.pack("!L", self.capabilities))
+        packed.append(struct.pack("!B", self.max_bands))
+        packed.append(struct.pack("!B", self.max_color))
+        packed.append('\x00' * 2)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = meter_features()
+        obj.max_meter = reader.read("!L")[0]
+        obj.band_types = reader.read("!L")[0]
+        obj.capabilities = reader.read("!L")[0]
+        obj.max_bands = reader.read("!B")[0]
+        obj.max_color = reader.read("!B")[0]
+        reader.skip(2)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.max_meter != other.max_meter: return False
+        if self.band_types != other.band_types: return False
+        if self.capabilities != other.capabilities: return False
+        if self.max_bands != other.max_bands: return False
+        if self.max_color != other.max_color: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("meter_features {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("max_meter = ");
+                q.text("%#x" % self.max_meter)
+                q.text(","); q.breakable()
+                q.text("band_types = ");
+                q.text("%#x" % self.band_types)
+                q.text(","); q.breakable()
+                q.text("capabilities = ");
+                q.text("%#x" % self.capabilities)
+                q.text(","); q.breakable()
+                q.text("max_bands = ");
+                q.text("%#x" % self.max_bands)
+                q.text(","); q.breakable()
+                q.text("max_color = ");
+                q.text("%#x" % self.max_color)
+            q.breakable()
+        q.text('}')
+
+
+class meter_stats(loxi.OFObject):
+
+    def __init__(self, meter_id=None, flow_count=None, packet_in_count=None, byte_in_count=None, duration_sec=None, duration_nsec=None, band_stats=None):
+        if meter_id != None:
+            self.meter_id = meter_id
+        else:
+            self.meter_id = 0
+        if flow_count != None:
+            self.flow_count = flow_count
+        else:
+            self.flow_count = 0
+        if packet_in_count != None:
+            self.packet_in_count = packet_in_count
+        else:
+            self.packet_in_count = 0
+        if byte_in_count != None:
+            self.byte_in_count = byte_in_count
+        else:
+            self.byte_in_count = 0
+        if duration_sec != None:
+            self.duration_sec = duration_sec
+        else:
+            self.duration_sec = 0
+        if duration_nsec != None:
+            self.duration_nsec = duration_nsec
+        else:
+            self.duration_nsec = 0
+        if band_stats != None:
+            self.band_stats = band_stats
+        else:
+            self.band_stats = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.meter_id))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 6)
+        packed.append(struct.pack("!L", self.flow_count))
+        packed.append(struct.pack("!Q", self.packet_in_count))
+        packed.append(struct.pack("!Q", self.byte_in_count))
+        packed.append(struct.pack("!L", self.duration_sec))
+        packed.append(struct.pack("!L", self.duration_nsec))
+        packed.append(loxi.generic_util.pack_list(self.band_stats))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = meter_stats()
+        obj.meter_id = reader.read("!L")[0]
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 6)
+        reader.skip(6)
+        obj.flow_count = reader.read("!L")[0]
+        obj.packet_in_count = reader.read("!Q")[0]
+        obj.byte_in_count = reader.read("!Q")[0]
+        obj.duration_sec = reader.read("!L")[0]
+        obj.duration_nsec = reader.read("!L")[0]
+        obj.band_stats = loxi.generic_util.unpack_list(reader, ofp.common.meter_band_stats.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.meter_id != other.meter_id: return False
+        if self.flow_count != other.flow_count: return False
+        if self.packet_in_count != other.packet_in_count: return False
+        if self.byte_in_count != other.byte_in_count: return False
+        if self.duration_sec != other.duration_sec: return False
+        if self.duration_nsec != other.duration_nsec: return False
+        if self.band_stats != other.band_stats: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("meter_stats {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("meter_id = ");
+                q.text("%#x" % self.meter_id)
+                q.text(","); q.breakable()
+                q.text("flow_count = ");
+                q.text("%#x" % self.flow_count)
+                q.text(","); q.breakable()
+                q.text("packet_in_count = ");
+                q.text("%#x" % self.packet_in_count)
+                q.text(","); q.breakable()
+                q.text("byte_in_count = ");
+                q.text("%#x" % self.byte_in_count)
+                q.text(","); q.breakable()
+                q.text("duration_sec = ");
+                q.text("%#x" % self.duration_sec)
+                q.text(","); q.breakable()
+                q.text("duration_nsec = ");
+                q.text("%#x" % self.duration_nsec)
+                q.text(","); q.breakable()
+                q.text("band_stats = ");
+                q.pp(self.band_stats)
+            q.breakable()
+        q.text('}')
+
+
+class packet_queue(loxi.OFObject):
+
+    def __init__(self, queue_id=None, port=None, properties=None):
+        if queue_id != None:
+            self.queue_id = queue_id
+        else:
+            self.queue_id = 0
+        if port != None:
+            self.port = port
+        else:
+            self.port = 0
+        if properties != None:
+            self.properties = properties
+        else:
+            self.properties = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.queue_id))
+        packed.append(util.pack_port_no(self.port))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 2
+        packed.append('\x00' * 6)
+        packed.append(loxi.generic_util.pack_list(self.properties))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = packet_queue()
+        obj.queue_id = reader.read("!L")[0]
+        obj.port = util.unpack_port_no(reader)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 10)
+        reader.skip(6)
+        obj.properties = loxi.generic_util.unpack_list(reader, ofp.common.queue_prop.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.queue_id != other.queue_id: return False
+        if self.port != other.port: return False
+        if self.properties != other.properties: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("packet_queue {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("queue_id = ");
+                q.text("%#x" % self.queue_id)
+                q.text(","); q.breakable()
+                q.text("port = ");
+                q.text(util.pretty_port(self.port))
+                q.text(","); q.breakable()
+                q.text("properties = ");
+                q.pp(self.properties)
+            q.breakable()
+        q.text('}')
+
+
+class port_desc(loxi.OFObject):
+
+    def __init__(self, port_no=None, hw_addr=None, name=None, config=None, state=None, curr=None, advertised=None, supported=None, peer=None, curr_speed=None, max_speed=None):
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if hw_addr != None:
+            self.hw_addr = hw_addr
+        else:
+            self.hw_addr = [0,0,0,0,0,0]
+        if name != None:
+            self.name = name
+        else:
+            self.name = ""
+        if config != None:
+            self.config = config
+        else:
+            self.config = 0
+        if state != None:
+            self.state = state
+        else:
+            self.state = 0
+        if curr != None:
+            self.curr = curr
+        else:
+            self.curr = 0
+        if advertised != None:
+            self.advertised = advertised
+        else:
+            self.advertised = 0
+        if supported != None:
+            self.supported = supported
+        else:
+            self.supported = 0
+        if peer != None:
+            self.peer = peer
+        else:
+            self.peer = 0
+        if curr_speed != None:
+            self.curr_speed = curr_speed
+        else:
+            self.curr_speed = 0
+        if max_speed != None:
+            self.max_speed = max_speed
+        else:
+            self.max_speed = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!6B", *self.hw_addr))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!16s", self.name))
+        packed.append(struct.pack("!L", self.config))
+        packed.append(struct.pack("!L", self.state))
+        packed.append(struct.pack("!L", self.curr))
+        packed.append(struct.pack("!L", self.advertised))
+        packed.append(struct.pack("!L", self.supported))
+        packed.append(struct.pack("!L", self.peer))
+        packed.append(struct.pack("!L", self.curr_speed))
+        packed.append(struct.pack("!L", self.max_speed))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_desc()
+        obj.port_no = util.unpack_port_no(reader)
+        reader.skip(4)
+        obj.hw_addr = list(reader.read('!6B'))
+        reader.skip(2)
+        obj.name = reader.read("!16s")[0].rstrip("\x00")
+        obj.config = reader.read("!L")[0]
+        obj.state = reader.read("!L")[0]
+        obj.curr = reader.read("!L")[0]
+        obj.advertised = reader.read("!L")[0]
+        obj.supported = reader.read("!L")[0]
+        obj.peer = reader.read("!L")[0]
+        obj.curr_speed = reader.read("!L")[0]
+        obj.max_speed = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.port_no != other.port_no: return False
+        if self.hw_addr != other.hw_addr: return False
+        if self.name != other.name: return False
+        if self.config != other.config: return False
+        if self.state != other.state: return False
+        if self.curr != other.curr: return False
+        if self.advertised != other.advertised: return False
+        if self.supported != other.supported: return False
+        if self.peer != other.peer: return False
+        if self.curr_speed != other.curr_speed: return False
+        if self.max_speed != other.max_speed: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_desc {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("hw_addr = ");
+                q.text(util.pretty_mac(self.hw_addr))
+                q.text(","); q.breakable()
+                q.text("name = ");
+                q.pp(self.name)
+                q.text(","); q.breakable()
+                q.text("config = ");
+                q.text("%#x" % self.config)
+                q.text(","); q.breakable()
+                q.text("state = ");
+                q.text("%#x" % self.state)
+                q.text(","); q.breakable()
+                q.text("curr = ");
+                q.text("%#x" % self.curr)
+                q.text(","); q.breakable()
+                q.text("advertised = ");
+                q.text("%#x" % self.advertised)
+                q.text(","); q.breakable()
+                q.text("supported = ");
+                q.text("%#x" % self.supported)
+                q.text(","); q.breakable()
+                q.text("peer = ");
+                q.text("%#x" % self.peer)
+                q.text(","); q.breakable()
+                q.text("curr_speed = ");
+                q.text("%#x" % self.curr_speed)
+                q.text(","); q.breakable()
+                q.text("max_speed = ");
+                q.text("%#x" % self.max_speed)
+            q.breakable()
+        q.text('}')
+
+
+class port_stats_entry(loxi.OFObject):
+
+    def __init__(self, port_no=None, rx_packets=None, tx_packets=None, rx_bytes=None, tx_bytes=None, rx_dropped=None, tx_dropped=None, rx_errors=None, tx_errors=None, rx_frame_err=None, rx_over_err=None, rx_crc_err=None, collisions=None, duration_sec=None, duration_nsec=None):
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if rx_packets != None:
+            self.rx_packets = rx_packets
+        else:
+            self.rx_packets = 0
+        if tx_packets != None:
+            self.tx_packets = tx_packets
+        else:
+            self.tx_packets = 0
+        if rx_bytes != None:
+            self.rx_bytes = rx_bytes
+        else:
+            self.rx_bytes = 0
+        if tx_bytes != None:
+            self.tx_bytes = tx_bytes
+        else:
+            self.tx_bytes = 0
+        if rx_dropped != None:
+            self.rx_dropped = rx_dropped
+        else:
+            self.rx_dropped = 0
+        if tx_dropped != None:
+            self.tx_dropped = tx_dropped
+        else:
+            self.tx_dropped = 0
+        if rx_errors != None:
+            self.rx_errors = rx_errors
+        else:
+            self.rx_errors = 0
+        if tx_errors != None:
+            self.tx_errors = tx_errors
+        else:
+            self.tx_errors = 0
+        if rx_frame_err != None:
+            self.rx_frame_err = rx_frame_err
+        else:
+            self.rx_frame_err = 0
+        if rx_over_err != None:
+            self.rx_over_err = rx_over_err
+        else:
+            self.rx_over_err = 0
+        if rx_crc_err != None:
+            self.rx_crc_err = rx_crc_err
+        else:
+            self.rx_crc_err = 0
+        if collisions != None:
+            self.collisions = collisions
+        else:
+            self.collisions = 0
+        if duration_sec != None:
+            self.duration_sec = duration_sec
+        else:
+            self.duration_sec = 0
+        if duration_nsec != None:
+            self.duration_nsec = duration_nsec
+        else:
+            self.duration_nsec = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!Q", self.rx_packets))
+        packed.append(struct.pack("!Q", self.tx_packets))
+        packed.append(struct.pack("!Q", self.rx_bytes))
+        packed.append(struct.pack("!Q", self.tx_bytes))
+        packed.append(struct.pack("!Q", self.rx_dropped))
+        packed.append(struct.pack("!Q", self.tx_dropped))
+        packed.append(struct.pack("!Q", self.rx_errors))
+        packed.append(struct.pack("!Q", self.tx_errors))
+        packed.append(struct.pack("!Q", self.rx_frame_err))
+        packed.append(struct.pack("!Q", self.rx_over_err))
+        packed.append(struct.pack("!Q", self.rx_crc_err))
+        packed.append(struct.pack("!Q", self.collisions))
+        packed.append(struct.pack("!L", self.duration_sec))
+        packed.append(struct.pack("!L", self.duration_nsec))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_stats_entry()
+        obj.port_no = util.unpack_port_no(reader)
+        reader.skip(4)
+        obj.rx_packets = reader.read("!Q")[0]
+        obj.tx_packets = reader.read("!Q")[0]
+        obj.rx_bytes = reader.read("!Q")[0]
+        obj.tx_bytes = reader.read("!Q")[0]
+        obj.rx_dropped = reader.read("!Q")[0]
+        obj.tx_dropped = reader.read("!Q")[0]
+        obj.rx_errors = reader.read("!Q")[0]
+        obj.tx_errors = reader.read("!Q")[0]
+        obj.rx_frame_err = reader.read("!Q")[0]
+        obj.rx_over_err = reader.read("!Q")[0]
+        obj.rx_crc_err = reader.read("!Q")[0]
+        obj.collisions = reader.read("!Q")[0]
+        obj.duration_sec = reader.read("!L")[0]
+        obj.duration_nsec = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.port_no != other.port_no: return False
+        if self.rx_packets != other.rx_packets: return False
+        if self.tx_packets != other.tx_packets: return False
+        if self.rx_bytes != other.rx_bytes: return False
+        if self.tx_bytes != other.tx_bytes: return False
+        if self.rx_dropped != other.rx_dropped: return False
+        if self.tx_dropped != other.tx_dropped: return False
+        if self.rx_errors != other.rx_errors: return False
+        if self.tx_errors != other.tx_errors: return False
+        if self.rx_frame_err != other.rx_frame_err: return False
+        if self.rx_over_err != other.rx_over_err: return False
+        if self.rx_crc_err != other.rx_crc_err: return False
+        if self.collisions != other.collisions: return False
+        if self.duration_sec != other.duration_sec: return False
+        if self.duration_nsec != other.duration_nsec: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("rx_packets = ");
+                q.text("%#x" % self.rx_packets)
+                q.text(","); q.breakable()
+                q.text("tx_packets = ");
+                q.text("%#x" % self.tx_packets)
+                q.text(","); q.breakable()
+                q.text("rx_bytes = ");
+                q.text("%#x" % self.rx_bytes)
+                q.text(","); q.breakable()
+                q.text("tx_bytes = ");
+                q.text("%#x" % self.tx_bytes)
+                q.text(","); q.breakable()
+                q.text("rx_dropped = ");
+                q.text("%#x" % self.rx_dropped)
+                q.text(","); q.breakable()
+                q.text("tx_dropped = ");
+                q.text("%#x" % self.tx_dropped)
+                q.text(","); q.breakable()
+                q.text("rx_errors = ");
+                q.text("%#x" % self.rx_errors)
+                q.text(","); q.breakable()
+                q.text("tx_errors = ");
+                q.text("%#x" % self.tx_errors)
+                q.text(","); q.breakable()
+                q.text("rx_frame_err = ");
+                q.text("%#x" % self.rx_frame_err)
+                q.text(","); q.breakable()
+                q.text("rx_over_err = ");
+                q.text("%#x" % self.rx_over_err)
+                q.text(","); q.breakable()
+                q.text("rx_crc_err = ");
+                q.text("%#x" % self.rx_crc_err)
+                q.text(","); q.breakable()
+                q.text("collisions = ");
+                q.text("%#x" % self.collisions)
+                q.text(","); q.breakable()
+                q.text("duration_sec = ");
+                q.text("%#x" % self.duration_sec)
+                q.text(","); q.breakable()
+                q.text("duration_nsec = ");
+                q.text("%#x" % self.duration_nsec)
+            q.breakable()
+        q.text('}')
+
+
+class queue_prop(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = queue_prop.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = queue_prop()
+        obj.type = reader.read("!H")[0]
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_prop {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class queue_prop_experimenter(queue_prop):
+    subtypes = {}
+
+    type = 65535
+
+    def __init__(self, experimenter=None, data=None):
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append('\x00' * 4)
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 8)
+        subclass = queue_prop_experimenter.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = queue_prop_experimenter()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        obj.experimenter = reader.read("!L")[0]
+        reader.skip(4)
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.experimenter != other.experimenter: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_prop_experimenter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+queue_prop.subtypes[65535] = queue_prop_experimenter
+
+class queue_prop_max_rate(queue_prop):
+    type = 2
+
+    def __init__(self, rate=None):
+        if rate != None:
+            self.rate = rate
+        else:
+            self.rate = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!H", self.rate))
+        packed.append('\x00' * 6)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_prop_max_rate()
+        _type = reader.read("!H")[0]
+        assert(_type == 2)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        obj.rate = reader.read("!H")[0]
+        reader.skip(6)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.rate != other.rate: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_prop_max_rate {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("rate = ");
+                q.text("%#x" % self.rate)
+            q.breakable()
+        q.text('}')
+
+queue_prop.subtypes[2] = queue_prop_max_rate
+
+class queue_prop_min_rate(queue_prop):
+    type = 1
+
+    def __init__(self, rate=None):
+        if rate != None:
+            self.rate = rate
+        else:
+            self.rate = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!H", self.rate))
+        packed.append('\x00' * 6)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_prop_min_rate()
+        _type = reader.read("!H")[0]
+        assert(_type == 1)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        obj.rate = reader.read("!H")[0]
+        reader.skip(6)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.rate != other.rate: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_prop_min_rate {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("rate = ");
+                q.text("%#x" % self.rate)
+            q.breakable()
+        q.text('}')
+
+queue_prop.subtypes[1] = queue_prop_min_rate
+
+class queue_stats_entry(loxi.OFObject):
+
+    def __init__(self, port_no=None, queue_id=None, tx_bytes=None, tx_packets=None, tx_errors=None, duration_sec=None, duration_nsec=None):
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if queue_id != None:
+            self.queue_id = queue_id
+        else:
+            self.queue_id = 0
+        if tx_bytes != None:
+            self.tx_bytes = tx_bytes
+        else:
+            self.tx_bytes = 0
+        if tx_packets != None:
+            self.tx_packets = tx_packets
+        else:
+            self.tx_packets = 0
+        if tx_errors != None:
+            self.tx_errors = tx_errors
+        else:
+            self.tx_errors = 0
+        if duration_sec != None:
+            self.duration_sec = duration_sec
+        else:
+            self.duration_sec = 0
+        if duration_nsec != None:
+            self.duration_nsec = duration_nsec
+        else:
+            self.duration_nsec = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!L", self.queue_id))
+        packed.append(struct.pack("!Q", self.tx_bytes))
+        packed.append(struct.pack("!Q", self.tx_packets))
+        packed.append(struct.pack("!Q", self.tx_errors))
+        packed.append(struct.pack("!L", self.duration_sec))
+        packed.append(struct.pack("!L", self.duration_nsec))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_stats_entry()
+        obj.port_no = util.unpack_port_no(reader)
+        obj.queue_id = reader.read("!L")[0]
+        obj.tx_bytes = reader.read("!Q")[0]
+        obj.tx_packets = reader.read("!Q")[0]
+        obj.tx_errors = reader.read("!Q")[0]
+        obj.duration_sec = reader.read("!L")[0]
+        obj.duration_nsec = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.port_no != other.port_no: return False
+        if self.queue_id != other.queue_id: return False
+        if self.tx_bytes != other.tx_bytes: return False
+        if self.tx_packets != other.tx_packets: return False
+        if self.tx_errors != other.tx_errors: return False
+        if self.duration_sec != other.duration_sec: return False
+        if self.duration_nsec != other.duration_nsec: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("queue_id = ");
+                q.text("%#x" % self.queue_id)
+                q.text(","); q.breakable()
+                q.text("tx_bytes = ");
+                q.text("%#x" % self.tx_bytes)
+                q.text(","); q.breakable()
+                q.text("tx_packets = ");
+                q.text("%#x" % self.tx_packets)
+                q.text(","); q.breakable()
+                q.text("tx_errors = ");
+                q.text("%#x" % self.tx_errors)
+                q.text(","); q.breakable()
+                q.text("duration_sec = ");
+                q.text("%#x" % self.duration_sec)
+                q.text(","); q.breakable()
+                q.text("duration_nsec = ");
+                q.text("%#x" % self.duration_nsec)
+            q.breakable()
+        q.text('}')
+
+
+class table_feature_prop(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = table_feature_prop.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = table_feature_prop()
+        obj.type = reader.read("!H")[0]
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_feature_prop {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class table_feature_prop_apply_actions(table_feature_prop):
+    type = 6
+
+    def __init__(self, action_ids=None):
+        if action_ids != None:
+            self.action_ids = action_ids
+        else:
+            self.action_ids = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(loxi.generic_util.pack_list(self.action_ids))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        packed.append(loxi.generic_util.pad_to(8, length))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_feature_prop_apply_actions()
+        _type = reader.read("!H")[0]
+        assert(_type == 6)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.action_ids = loxi.generic_util.unpack_list(reader, ofp.action_id.action_id.unpack)
+        orig_reader.skip_align()
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.action_ids != other.action_ids: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_feature_prop_apply_actions {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("action_ids = ");
+                q.pp(self.action_ids)
+            q.breakable()
+        q.text('}')
+
+table_feature_prop.subtypes[6] = table_feature_prop_apply_actions
+
+class table_feature_prop_apply_actions_miss(table_feature_prop):
+    type = 7
+
+    def __init__(self, action_ids=None):
+        if action_ids != None:
+            self.action_ids = action_ids
+        else:
+            self.action_ids = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(loxi.generic_util.pack_list(self.action_ids))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        packed.append(loxi.generic_util.pad_to(8, length))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_feature_prop_apply_actions_miss()
+        _type = reader.read("!H")[0]
+        assert(_type == 7)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.action_ids = loxi.generic_util.unpack_list(reader, ofp.action_id.action_id.unpack)
+        orig_reader.skip_align()
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.action_ids != other.action_ids: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_feature_prop_apply_actions_miss {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("action_ids = ");
+                q.pp(self.action_ids)
+            q.breakable()
+        q.text('}')
+
+table_feature_prop.subtypes[7] = table_feature_prop_apply_actions_miss
+
+class table_feature_prop_apply_setfield(table_feature_prop):
+    type = 14
+
+    def __init__(self, oxm_ids=None):
+        if oxm_ids != None:
+            self.oxm_ids = oxm_ids
+        else:
+            self.oxm_ids = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(loxi.generic_util.pack_list(self.oxm_ids))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        packed.append(loxi.generic_util.pad_to(8, length))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_feature_prop_apply_setfield()
+        _type = reader.read("!H")[0]
+        assert(_type == 14)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.oxm_ids = loxi.generic_util.unpack_list(reader, ofp.common.uint32.unpack)
+        orig_reader.skip_align()
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.oxm_ids != other.oxm_ids: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_feature_prop_apply_setfield {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("oxm_ids = ");
+                q.pp(self.oxm_ids)
+            q.breakable()
+        q.text('}')
+
+table_feature_prop.subtypes[14] = table_feature_prop_apply_setfield
+
+class table_feature_prop_apply_setfield_miss(table_feature_prop):
+    type = 15
+
+    def __init__(self, oxm_ids=None):
+        if oxm_ids != None:
+            self.oxm_ids = oxm_ids
+        else:
+            self.oxm_ids = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(loxi.generic_util.pack_list(self.oxm_ids))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        packed.append(loxi.generic_util.pad_to(8, length))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_feature_prop_apply_setfield_miss()
+        _type = reader.read("!H")[0]
+        assert(_type == 15)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.oxm_ids = loxi.generic_util.unpack_list(reader, ofp.common.uint32.unpack)
+        orig_reader.skip_align()
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.oxm_ids != other.oxm_ids: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_feature_prop_apply_setfield_miss {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("oxm_ids = ");
+                q.pp(self.oxm_ids)
+            q.breakable()
+        q.text('}')
+
+table_feature_prop.subtypes[15] = table_feature_prop_apply_setfield_miss
+
+class table_feature_prop_experimenter(table_feature_prop):
+    subtypes = {}
+
+    type = 65534
+
+    def __init__(self, experimenter=None, subtype=None, experimenter_data=None):
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        if experimenter_data != None:
+            self.experimenter_data = experimenter_data
+        else:
+            self.experimenter_data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(self.experimenter_data)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        packed.append(loxi.generic_util.pad_to(8, length))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 4)
+        subclass = table_feature_prop_experimenter.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = table_feature_prop_experimenter()
+        _type = reader.read("!H")[0]
+        assert(_type == 65534)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.experimenter = reader.read("!L")[0]
+        obj.subtype = reader.read("!L")[0]
+        obj.experimenter_data = str(reader.read_all())
+        orig_reader.skip_align()
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.experimenter != other.experimenter: return False
+        if self.subtype != other.subtype: return False
+        if self.experimenter_data != other.experimenter_data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_feature_prop_experimenter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("subtype = ");
+                q.text("%#x" % self.subtype)
+                q.text(","); q.breakable()
+                q.text("experimenter_data = ");
+                q.pp(self.experimenter_data)
+            q.breakable()
+        q.text('}')
+
+table_feature_prop.subtypes[65534] = table_feature_prop_experimenter
+
+class table_feature_prop_experimenter_miss(table_feature_prop):
+    subtypes = {}
+
+    type = 65535
+
+    def __init__(self, experimenter=None, subtype=None, experimenter_data=None):
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        if experimenter_data != None:
+            self.experimenter_data = experimenter_data
+        else:
+            self.experimenter_data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(self.experimenter_data)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        packed.append(loxi.generic_util.pad_to(8, length))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 4)
+        subclass = table_feature_prop_experimenter_miss.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = table_feature_prop_experimenter_miss()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.experimenter = reader.read("!L")[0]
+        obj.subtype = reader.read("!L")[0]
+        obj.experimenter_data = str(reader.read_all())
+        orig_reader.skip_align()
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.experimenter != other.experimenter: return False
+        if self.subtype != other.subtype: return False
+        if self.experimenter_data != other.experimenter_data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_feature_prop_experimenter_miss {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("subtype = ");
+                q.text("%#x" % self.subtype)
+                q.text(","); q.breakable()
+                q.text("experimenter_data = ");
+                q.pp(self.experimenter_data)
+            q.breakable()
+        q.text('}')
+
+table_feature_prop.subtypes[65535] = table_feature_prop_experimenter_miss
+
+class table_feature_prop_instructions(table_feature_prop):
+    type = 0
+
+    def __init__(self, instruction_ids=None):
+        if instruction_ids != None:
+            self.instruction_ids = instruction_ids
+        else:
+            self.instruction_ids = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(loxi.generic_util.pack_list(self.instruction_ids))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        packed.append(loxi.generic_util.pad_to(8, length))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_feature_prop_instructions()
+        _type = reader.read("!H")[0]
+        assert(_type == 0)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.instruction_ids = loxi.generic_util.unpack_list(reader, ofp.instruction_id.instruction_id.unpack)
+        orig_reader.skip_align()
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.instruction_ids != other.instruction_ids: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_feature_prop_instructions {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("instruction_ids = ");
+                q.pp(self.instruction_ids)
+            q.breakable()
+        q.text('}')
+
+table_feature_prop.subtypes[0] = table_feature_prop_instructions
+
+class table_feature_prop_instructions_miss(table_feature_prop):
+    type = 1
+
+    def __init__(self, instruction_ids=None):
+        if instruction_ids != None:
+            self.instruction_ids = instruction_ids
+        else:
+            self.instruction_ids = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(loxi.generic_util.pack_list(self.instruction_ids))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        packed.append(loxi.generic_util.pad_to(8, length))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_feature_prop_instructions_miss()
+        _type = reader.read("!H")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.instruction_ids = loxi.generic_util.unpack_list(reader, ofp.instruction_id.instruction_id.unpack)
+        orig_reader.skip_align()
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.instruction_ids != other.instruction_ids: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_feature_prop_instructions_miss {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("instruction_ids = ");
+                q.pp(self.instruction_ids)
+            q.breakable()
+        q.text('}')
+
+table_feature_prop.subtypes[1] = table_feature_prop_instructions_miss
+
+class table_feature_prop_match(table_feature_prop):
+    type = 8
+
+    def __init__(self, oxm_ids=None):
+        if oxm_ids != None:
+            self.oxm_ids = oxm_ids
+        else:
+            self.oxm_ids = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(loxi.generic_util.pack_list(self.oxm_ids))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        packed.append(loxi.generic_util.pad_to(8, length))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_feature_prop_match()
+        _type = reader.read("!H")[0]
+        assert(_type == 8)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.oxm_ids = loxi.generic_util.unpack_list(reader, ofp.common.uint32.unpack)
+        orig_reader.skip_align()
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.oxm_ids != other.oxm_ids: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_feature_prop_match {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("oxm_ids = ");
+                q.pp(self.oxm_ids)
+            q.breakable()
+        q.text('}')
+
+table_feature_prop.subtypes[8] = table_feature_prop_match
+
+class table_feature_prop_next_tables(table_feature_prop):
+    type = 2
+
+    def __init__(self, next_table_ids=None):
+        if next_table_ids != None:
+            self.next_table_ids = next_table_ids
+        else:
+            self.next_table_ids = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(loxi.generic_util.pack_list(self.next_table_ids))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        packed.append(loxi.generic_util.pad_to(8, length))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_feature_prop_next_tables()
+        _type = reader.read("!H")[0]
+        assert(_type == 2)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.next_table_ids = loxi.generic_util.unpack_list(reader, ofp.common.uint8.unpack)
+        orig_reader.skip_align()
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.next_table_ids != other.next_table_ids: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_feature_prop_next_tables {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("next_table_ids = ");
+                q.pp(self.next_table_ids)
+            q.breakable()
+        q.text('}')
+
+table_feature_prop.subtypes[2] = table_feature_prop_next_tables
+
+class table_feature_prop_next_tables_miss(table_feature_prop):
+    type = 3
+
+    def __init__(self, next_table_ids=None):
+        if next_table_ids != None:
+            self.next_table_ids = next_table_ids
+        else:
+            self.next_table_ids = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(loxi.generic_util.pack_list(self.next_table_ids))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        packed.append(loxi.generic_util.pad_to(8, length))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_feature_prop_next_tables_miss()
+        _type = reader.read("!H")[0]
+        assert(_type == 3)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.next_table_ids = loxi.generic_util.unpack_list(reader, ofp.common.uint8.unpack)
+        orig_reader.skip_align()
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.next_table_ids != other.next_table_ids: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_feature_prop_next_tables_miss {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("next_table_ids = ");
+                q.pp(self.next_table_ids)
+            q.breakable()
+        q.text('}')
+
+table_feature_prop.subtypes[3] = table_feature_prop_next_tables_miss
+
+class table_feature_prop_wildcards(table_feature_prop):
+    type = 10
+
+    def __init__(self, oxm_ids=None):
+        if oxm_ids != None:
+            self.oxm_ids = oxm_ids
+        else:
+            self.oxm_ids = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(loxi.generic_util.pack_list(self.oxm_ids))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        packed.append(loxi.generic_util.pad_to(8, length))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_feature_prop_wildcards()
+        _type = reader.read("!H")[0]
+        assert(_type == 10)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.oxm_ids = loxi.generic_util.unpack_list(reader, ofp.common.uint32.unpack)
+        orig_reader.skip_align()
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.oxm_ids != other.oxm_ids: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_feature_prop_wildcards {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("oxm_ids = ");
+                q.pp(self.oxm_ids)
+            q.breakable()
+        q.text('}')
+
+table_feature_prop.subtypes[10] = table_feature_prop_wildcards
+
+class table_feature_prop_write_actions(table_feature_prop):
+    type = 4
+
+    def __init__(self, action_ids=None):
+        if action_ids != None:
+            self.action_ids = action_ids
+        else:
+            self.action_ids = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(loxi.generic_util.pack_list(self.action_ids))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        packed.append(loxi.generic_util.pad_to(8, length))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_feature_prop_write_actions()
+        _type = reader.read("!H")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.action_ids = loxi.generic_util.unpack_list(reader, ofp.action_id.action_id.unpack)
+        orig_reader.skip_align()
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.action_ids != other.action_ids: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_feature_prop_write_actions {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("action_ids = ");
+                q.pp(self.action_ids)
+            q.breakable()
+        q.text('}')
+
+table_feature_prop.subtypes[4] = table_feature_prop_write_actions
+
+class table_feature_prop_write_actions_miss(table_feature_prop):
+    type = 5
+
+    def __init__(self, action_ids=None):
+        if action_ids != None:
+            self.action_ids = action_ids
+        else:
+            self.action_ids = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(loxi.generic_util.pack_list(self.action_ids))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        packed.append(loxi.generic_util.pad_to(8, length))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_feature_prop_write_actions_miss()
+        _type = reader.read("!H")[0]
+        assert(_type == 5)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.action_ids = loxi.generic_util.unpack_list(reader, ofp.action_id.action_id.unpack)
+        orig_reader.skip_align()
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.action_ids != other.action_ids: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_feature_prop_write_actions_miss {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("action_ids = ");
+                q.pp(self.action_ids)
+            q.breakable()
+        q.text('}')
+
+table_feature_prop.subtypes[5] = table_feature_prop_write_actions_miss
+
+class table_feature_prop_write_setfield(table_feature_prop):
+    type = 12
+
+    def __init__(self, oxm_ids=None):
+        if oxm_ids != None:
+            self.oxm_ids = oxm_ids
+        else:
+            self.oxm_ids = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(loxi.generic_util.pack_list(self.oxm_ids))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        packed.append(loxi.generic_util.pad_to(8, length))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_feature_prop_write_setfield()
+        _type = reader.read("!H")[0]
+        assert(_type == 12)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.oxm_ids = loxi.generic_util.unpack_list(reader, ofp.common.uint32.unpack)
+        orig_reader.skip_align()
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.oxm_ids != other.oxm_ids: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_feature_prop_write_setfield {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("oxm_ids = ");
+                q.pp(self.oxm_ids)
+            q.breakable()
+        q.text('}')
+
+table_feature_prop.subtypes[12] = table_feature_prop_write_setfield
+
+class table_feature_prop_write_setfield_miss(table_feature_prop):
+    type = 13
+
+    def __init__(self, oxm_ids=None):
+        if oxm_ids != None:
+            self.oxm_ids = oxm_ids
+        else:
+            self.oxm_ids = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(loxi.generic_util.pack_list(self.oxm_ids))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        packed.append(loxi.generic_util.pad_to(8, length))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_feature_prop_write_setfield_miss()
+        _type = reader.read("!H")[0]
+        assert(_type == 13)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.oxm_ids = loxi.generic_util.unpack_list(reader, ofp.common.uint32.unpack)
+        orig_reader.skip_align()
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.oxm_ids != other.oxm_ids: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_feature_prop_write_setfield_miss {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("oxm_ids = ");
+                q.pp(self.oxm_ids)
+            q.breakable()
+        q.text('}')
+
+table_feature_prop.subtypes[13] = table_feature_prop_write_setfield_miss
+
+class table_features(loxi.OFObject):
+
+    def __init__(self, table_id=None, name=None, metadata_match=None, metadata_write=None, config=None, max_entries=None, properties=None):
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if name != None:
+            self.name = name
+        else:
+            self.name = ""
+        if metadata_match != None:
+            self.metadata_match = metadata_match
+        else:
+            self.metadata_match = 0
+        if metadata_write != None:
+            self.metadata_write = metadata_write
+        else:
+            self.metadata_write = 0
+        if config != None:
+            self.config = config
+        else:
+            self.config = 0
+        if max_entries != None:
+            self.max_entries = max_entries
+        else:
+            self.max_entries = 0
+        if properties != None:
+            self.properties = properties
+        else:
+            self.properties = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 0
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append('\x00' * 5)
+        packed.append(struct.pack("!32s", self.name))
+        packed.append(struct.pack("!Q", self.metadata_match))
+        packed.append(struct.pack("!Q", self.metadata_write))
+        packed.append(struct.pack("!L", self.config))
+        packed.append(struct.pack("!L", self.max_entries))
+        packed.append(loxi.generic_util.pack_list(self.properties))
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_features()
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 2)
+        obj.table_id = reader.read("!B")[0]
+        reader.skip(5)
+        obj.name = reader.read("!32s")[0].rstrip("\x00")
+        obj.metadata_match = reader.read("!Q")[0]
+        obj.metadata_write = reader.read("!Q")[0]
+        obj.config = reader.read("!L")[0]
+        obj.max_entries = reader.read("!L")[0]
+        obj.properties = loxi.generic_util.unpack_list(reader, ofp.common.table_feature_prop.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.table_id != other.table_id: return False
+        if self.name != other.name: return False
+        if self.metadata_match != other.metadata_match: return False
+        if self.metadata_write != other.metadata_write: return False
+        if self.config != other.config: return False
+        if self.max_entries != other.max_entries: return False
+        if self.properties != other.properties: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_features {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("name = ");
+                q.pp(self.name)
+                q.text(","); q.breakable()
+                q.text("metadata_match = ");
+                q.text("%#x" % self.metadata_match)
+                q.text(","); q.breakable()
+                q.text("metadata_write = ");
+                q.text("%#x" % self.metadata_write)
+                q.text(","); q.breakable()
+                q.text("config = ");
+                q.text("%#x" % self.config)
+                q.text(","); q.breakable()
+                q.text("max_entries = ");
+                q.text("%#x" % self.max_entries)
+                q.text(","); q.breakable()
+                q.text("properties = ");
+                q.pp(self.properties)
+            q.breakable()
+        q.text('}')
+
+
+class table_stats_entry(loxi.OFObject):
+
+    def __init__(self, table_id=None, active_count=None, lookup_count=None, matched_count=None):
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if active_count != None:
+            self.active_count = active_count
+        else:
+            self.active_count = 0
+        if lookup_count != None:
+            self.lookup_count = lookup_count
+        else:
+            self.lookup_count = 0
+        if matched_count != None:
+            self.matched_count = matched_count
+        else:
+            self.matched_count = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append('\x00' * 3)
+        packed.append(struct.pack("!L", self.active_count))
+        packed.append(struct.pack("!Q", self.lookup_count))
+        packed.append(struct.pack("!Q", self.matched_count))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_stats_entry()
+        obj.table_id = reader.read("!B")[0]
+        reader.skip(3)
+        obj.active_count = reader.read("!L")[0]
+        obj.lookup_count = reader.read("!Q")[0]
+        obj.matched_count = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.table_id != other.table_id: return False
+        if self.active_count != other.active_count: return False
+        if self.lookup_count != other.lookup_count: return False
+        if self.matched_count != other.matched_count: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("active_count = ");
+                q.text("%#x" % self.active_count)
+                q.text(","); q.breakable()
+                q.text("lookup_count = ");
+                q.text("%#x" % self.lookup_count)
+                q.text(","); q.breakable()
+                q.text("matched_count = ");
+                q.text("%#x" % self.matched_count)
+            q.breakable()
+        q.text('}')
+
+
+class uint32(loxi.OFObject):
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = uint32()
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("uint32 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+
+class uint64(loxi.OFObject):
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!Q", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = uint64()
+        obj.value = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("uint64 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+
+class uint8(loxi.OFObject):
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = uint8()
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("uint8 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+
+
+match = match_v3
diff --git a/Fabric/Utilities/src/python/loxi/of13/const.py b/Fabric/Utilities/src/python/loxi/of13/const.py
new file mode 100644
index 0000000..f6a68eb
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of13/const.py
@@ -0,0 +1,1293 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template const.py
+# Do not modify
+
+OFP_VERSION = 4
+
+# Identifiers from group macro_definitions
+OFP_MAX_TABLE_NAME_LEN = 32
+OFP_MAX_PORT_NAME_LEN = 16
+OFP_TCP_PORT = 6653
+OFP_SSL_PORT = 6653
+OFP_ETH_ALEN = 6
+OFP_DEFAULT_MISS_SEND_LEN = 128
+OFP_VLAN_NONE = 0
+OFP_FLOW_PERMANENT = 0
+OFP_DEFAULT_PRIORITY = 32768
+OFP_NO_BUFFER = 4294967295
+DESC_STR_LEN = 256
+SERIAL_NUM_LEN = 32
+OFPQ_ALL = 4294967295
+OFPQ_MAX_RATE_UNCFG = 65535
+OFPQ_MIN_RATE_UNCFG = 65535
+
+# Identifiers from group of_bsn_lacp_convergence_status
+LACP_SUCCESS = 0
+LACP_TIMEDOUT = 1
+LACP_OUT_OF_SYNC = 2
+
+of_bsn_lacp_convergence_status_map = {
+    0: 'LACP_SUCCESS',
+    1: 'LACP_TIMEDOUT',
+    2: 'LACP_OUT_OF_SYNC',
+}
+
+# Identifiers from group of_bsn_pdu_slot_num
+BSN_PDU_SLOT_NUM_ANY = 255
+
+of_bsn_pdu_slot_num_map = {
+    255: 'BSN_PDU_SLOT_NUM_ANY',
+}
+
+# Identifiers from group of_bsn_vlan_counter
+OFP_BSN_VLAN_COUNTER_RX_BYTES = 0
+OFP_BSN_VLAN_COUNTER_RX_PACKETS = 1
+OFP_BSN_VLAN_COUNTER_TX_BYTES = 2
+OFP_BSN_VLAN_COUNTER_TX_PACKETS = 3
+
+of_bsn_vlan_counter_map = {
+    0: 'OFP_BSN_VLAN_COUNTER_RX_BYTES',
+    1: 'OFP_BSN_VLAN_COUNTER_RX_PACKETS',
+    2: 'OFP_BSN_VLAN_COUNTER_TX_BYTES',
+    3: 'OFP_BSN_VLAN_COUNTER_TX_PACKETS',
+}
+
+# Identifiers from group of_bsn_vrf_counter
+OFP_BSN_VRF_COUNTER_BYTES = 0
+OFP_BSN_VRF_COUNTER_PACKETS = 1
+
+of_bsn_vrf_counter_map = {
+    0: 'OFP_BSN_VRF_COUNTER_BYTES',
+    1: 'OFP_BSN_VRF_COUNTER_PACKETS',
+}
+
+# Identifiers from group ofp_action_type
+OFPAT_OUTPUT = 0
+OFPAT_COPY_TTL_OUT = 11
+OFPAT_COPY_TTL_IN = 12
+OFPAT_SET_MPLS_TTL = 15
+OFPAT_DEC_MPLS_TTL = 16
+OFPAT_PUSH_VLAN = 17
+OFPAT_POP_VLAN = 18
+OFPAT_PUSH_MPLS = 19
+OFPAT_POP_MPLS = 20
+OFPAT_SET_QUEUE = 21
+OFPAT_GROUP = 22
+OFPAT_SET_NW_TTL = 23
+OFPAT_DEC_NW_TTL = 24
+OFPAT_SET_FIELD = 25
+OFPAT_PUSH_PBB = 26
+OFPAT_POP_PBB = 27
+OFPAT_EXPERIMENTER = 65535
+
+ofp_action_type_map = {
+    0: 'OFPAT_OUTPUT',
+    11: 'OFPAT_COPY_TTL_OUT',
+    12: 'OFPAT_COPY_TTL_IN',
+    15: 'OFPAT_SET_MPLS_TTL',
+    16: 'OFPAT_DEC_MPLS_TTL',
+    17: 'OFPAT_PUSH_VLAN',
+    18: 'OFPAT_POP_VLAN',
+    19: 'OFPAT_PUSH_MPLS',
+    20: 'OFPAT_POP_MPLS',
+    21: 'OFPAT_SET_QUEUE',
+    22: 'OFPAT_GROUP',
+    23: 'OFPAT_SET_NW_TTL',
+    24: 'OFPAT_DEC_NW_TTL',
+    25: 'OFPAT_SET_FIELD',
+    26: 'OFPAT_PUSH_PBB',
+    27: 'OFPAT_POP_PBB',
+    65535: 'OFPAT_EXPERIMENTER',
+}
+
+# Identifiers from group ofp_bad_action_code
+OFPBAC_BAD_TYPE = 0
+OFPBAC_BAD_LEN = 1
+OFPBAC_BAD_EXPERIMENTER = 2
+OFPBAC_BAD_EXPERIMENTER_TYPE = 3
+OFPBAC_BAD_OUT_PORT = 4
+OFPBAC_BAD_ARGUMENT = 5
+OFPBAC_EPERM = 6
+OFPBAC_TOO_MANY = 7
+OFPBAC_BAD_QUEUE = 8
+OFPBAC_BAD_OUT_GROUP = 9
+OFPBAC_MATCH_INCONSISTENT = 10
+OFPBAC_UNSUPPORTED_ORDER = 11
+OFPBAC_BAD_TAG = 12
+OFPBAC_BAD_SET_TYPE = 13
+OFPBAC_BAD_SET_LEN = 14
+OFPBAC_BAD_SET_ARGUMENT = 15
+
+ofp_bad_action_code_map = {
+    0: 'OFPBAC_BAD_TYPE',
+    1: 'OFPBAC_BAD_LEN',
+    2: 'OFPBAC_BAD_EXPERIMENTER',
+    3: 'OFPBAC_BAD_EXPERIMENTER_TYPE',
+    4: 'OFPBAC_BAD_OUT_PORT',
+    5: 'OFPBAC_BAD_ARGUMENT',
+    6: 'OFPBAC_EPERM',
+    7: 'OFPBAC_TOO_MANY',
+    8: 'OFPBAC_BAD_QUEUE',
+    9: 'OFPBAC_BAD_OUT_GROUP',
+    10: 'OFPBAC_MATCH_INCONSISTENT',
+    11: 'OFPBAC_UNSUPPORTED_ORDER',
+    12: 'OFPBAC_BAD_TAG',
+    13: 'OFPBAC_BAD_SET_TYPE',
+    14: 'OFPBAC_BAD_SET_LEN',
+    15: 'OFPBAC_BAD_SET_ARGUMENT',
+}
+
+# Identifiers from group ofp_bad_instruction_code
+OFPBIC_UNKNOWN_INST = 0
+OFPBIC_UNSUP_INST = 1
+OFPBIC_BAD_TABLE_ID = 2
+OFPBIC_UNSUP_METADATA = 3
+OFPBIC_UNSUP_METADATA_MASK = 4
+OFPBIC_BAD_EXPERIMENTER = 5
+OFPBIC_BAD_EXPERIMENTER_TYPE = 6
+OFPBIC_BAD_LEN = 7
+OFPBIC_EPERM = 8
+
+ofp_bad_instruction_code_map = {
+    0: 'OFPBIC_UNKNOWN_INST',
+    1: 'OFPBIC_UNSUP_INST',
+    2: 'OFPBIC_BAD_TABLE_ID',
+    3: 'OFPBIC_UNSUP_METADATA',
+    4: 'OFPBIC_UNSUP_METADATA_MASK',
+    5: 'OFPBIC_BAD_EXPERIMENTER',
+    6: 'OFPBIC_BAD_EXPERIMENTER_TYPE',
+    7: 'OFPBIC_BAD_LEN',
+    8: 'OFPBIC_EPERM',
+}
+
+# Identifiers from group ofp_bad_match_code
+OFPBMC_BAD_TYPE = 0
+OFPBMC_BAD_LEN = 1
+OFPBMC_BAD_TAG = 2
+OFPBMC_BAD_DL_ADDR_MASK = 3
+OFPBMC_BAD_NW_ADDR_MASK = 4
+OFPBMC_BAD_WILDCARDS = 5
+OFPBMC_BAD_FIELD = 6
+OFPBMC_BAD_VALUE = 7
+OFPBMC_BAD_MASK = 8
+OFPBMC_BAD_PREREQ = 9
+OFPBMC_DUP_FIELD = 10
+OFPBMC_EPERM = 11
+
+ofp_bad_match_code_map = {
+    0: 'OFPBMC_BAD_TYPE',
+    1: 'OFPBMC_BAD_LEN',
+    2: 'OFPBMC_BAD_TAG',
+    3: 'OFPBMC_BAD_DL_ADDR_MASK',
+    4: 'OFPBMC_BAD_NW_ADDR_MASK',
+    5: 'OFPBMC_BAD_WILDCARDS',
+    6: 'OFPBMC_BAD_FIELD',
+    7: 'OFPBMC_BAD_VALUE',
+    8: 'OFPBMC_BAD_MASK',
+    9: 'OFPBMC_BAD_PREREQ',
+    10: 'OFPBMC_DUP_FIELD',
+    11: 'OFPBMC_EPERM',
+}
+
+# Identifiers from group ofp_bad_request_code
+OFPBRC_BAD_VERSION = 0
+OFPBRC_BAD_TYPE = 1
+OFPBRC_BAD_STAT = 2
+OFPBRC_BAD_EXPERIMENTER = 3
+OFPBRC_BAD_EXPERIMENTER_TYPE = 4
+OFPBRC_EPERM = 5
+OFPBRC_BAD_LEN = 6
+OFPBRC_BUFFER_EMPTY = 7
+OFPBRC_BUFFER_UNKNOWN = 8
+OFPBRC_BAD_TABLE_ID = 9
+OFPBRC_IS_SLAVE = 10
+OFPBRC_BAD_PORT = 11
+OFPBRC_BAD_PACKET = 12
+OFPBRC_MULTIPART_BUFFER_OVERFLOW = 13
+
+ofp_bad_request_code_map = {
+    0: 'OFPBRC_BAD_VERSION',
+    1: 'OFPBRC_BAD_TYPE',
+    2: 'OFPBRC_BAD_STAT',
+    3: 'OFPBRC_BAD_EXPERIMENTER',
+    4: 'OFPBRC_BAD_EXPERIMENTER_TYPE',
+    5: 'OFPBRC_EPERM',
+    6: 'OFPBRC_BAD_LEN',
+    7: 'OFPBRC_BUFFER_EMPTY',
+    8: 'OFPBRC_BUFFER_UNKNOWN',
+    9: 'OFPBRC_BAD_TABLE_ID',
+    10: 'OFPBRC_IS_SLAVE',
+    11: 'OFPBRC_BAD_PORT',
+    12: 'OFPBRC_BAD_PACKET',
+    13: 'OFPBRC_MULTIPART_BUFFER_OVERFLOW',
+}
+
+# Identifiers from group ofp_bsn_anchor
+OFP_BSN_ANCHOR_PACKET_START = 0
+OFP_BSN_ANCHOR_L3_HEADER_START = 1
+OFP_BSN_ANCHOR_L4_HEADER_START = 2
+OFP_BSN_ANCHOR_L4_PAYLOAD_START = 3
+
+ofp_bsn_anchor_map = {
+    0: 'OFP_BSN_ANCHOR_PACKET_START',
+    1: 'OFP_BSN_ANCHOR_L3_HEADER_START',
+    2: 'OFP_BSN_ANCHOR_L4_HEADER_START',
+    3: 'OFP_BSN_ANCHOR_L4_PAYLOAD_START',
+}
+
+# Identifiers from group ofp_bsn_controller_connection_state
+OFP_BSN_CONTROLLER_CONNECTION_STATE_DISCONNECTED = 0
+OFP_BSN_CONTROLLER_CONNECTION_STATE_CONNECTED = 1
+
+ofp_bsn_controller_connection_state_map = {
+    0: 'OFP_BSN_CONTROLLER_CONNECTION_STATE_DISCONNECTED',
+    1: 'OFP_BSN_CONTROLLER_CONNECTION_STATE_CONNECTED',
+}
+
+# Identifiers from group ofp_bsn_controller_role_reason
+OFP_BSN_CONTROLLER_ROLE_REASON_MASTER_REQUEST = 0
+OFP_BSN_CONTROLLER_ROLE_REASON_CONFIG = 1
+OFP_BSN_CONTROLLER_ROLE_REASON_EXPERIMENTER = 2
+
+ofp_bsn_controller_role_reason_map = {
+    0: 'OFP_BSN_CONTROLLER_ROLE_REASON_MASTER_REQUEST',
+    1: 'OFP_BSN_CONTROLLER_ROLE_REASON_CONFIG',
+    2: 'OFP_BSN_CONTROLLER_ROLE_REASON_EXPERIMENTER',
+}
+
+# Identifiers from group ofp_bsn_lacp_state
+OFP_BSN_LACP_STATE_ACTIVITY = 1
+OFP_BSN_LACP_STATE_TIMEOUT = 2
+OFP_BSN_LACP_STATE_AGGREGATION = 4
+OFP_BSN_LACP_STATE_SYNCHRONIZATION = 8
+OFP_BSN_LACP_STATE_COLLECTING = 16
+OFP_BSN_LACP_STATE_DISTRIBUTING = 32
+OFP_BSN_LACP_STATE_DEFAULTED = 64
+OFP_BSN_LACP_STATE_EXPIRED = 128
+
+ofp_bsn_lacp_state_map = {
+    1: 'OFP_BSN_LACP_STATE_ACTIVITY',
+    2: 'OFP_BSN_LACP_STATE_TIMEOUT',
+    4: 'OFP_BSN_LACP_STATE_AGGREGATION',
+    8: 'OFP_BSN_LACP_STATE_SYNCHRONIZATION',
+    16: 'OFP_BSN_LACP_STATE_COLLECTING',
+    32: 'OFP_BSN_LACP_STATE_DISTRIBUTING',
+    64: 'OFP_BSN_LACP_STATE_DEFAULTED',
+    128: 'OFP_BSN_LACP_STATE_EXPIRED',
+}
+
+# Identifiers from group ofp_bsn_loglevel
+OFP_BSN_LOGLEVEL_MSG = 0
+OFP_BSN_LOGLEVEL_ERROR = 1
+OFP_BSN_LOGLEVEL_WARN = 2
+OFP_BSN_LOGLEVEL_INFO = 3
+OFP_BSN_LOGLEVEL_VERBOSE = 4
+OFP_BSN_LOGLEVEL_TRACE = 5
+
+ofp_bsn_loglevel_map = {
+    0: 'OFP_BSN_LOGLEVEL_MSG',
+    1: 'OFP_BSN_LOGLEVEL_ERROR',
+    2: 'OFP_BSN_LOGLEVEL_WARN',
+    3: 'OFP_BSN_LOGLEVEL_INFO',
+    4: 'OFP_BSN_LOGLEVEL_VERBOSE',
+    5: 'OFP_BSN_LOGLEVEL_TRACE',
+}
+
+# Identifiers from group ofp_bsn_lua_upload_flags
+OFP_BSN_LUA_UPLOAD_MORE = 1
+OFP_BSN_LUA_UPLOAD_FORCE = 2
+
+ofp_bsn_lua_upload_flags_map = {
+    1: 'OFP_BSN_LUA_UPLOAD_MORE',
+    2: 'OFP_BSN_LUA_UPLOAD_FORCE',
+}
+
+# Identifiers from group ofp_bsn_pktin_flag
+OFP_BSN_PKTIN_FLAG_PDU = 1
+OFP_BSN_PKTIN_FLAG_NEW_HOST = 2
+OFP_BSN_PKTIN_FLAG_STATION_MOVE = 4
+OFP_BSN_PKTIN_FLAG_ARP = 8
+OFP_BSN_PKTIN_FLAG_DHCP = 16
+OFP_BSN_PKTIN_FLAG_L2_CPU = 32
+OFP_BSN_PKTIN_FLAG_DEBUG = 64
+OFP_BSN_PKTIN_FLAG_TTL_EXPIRED = 128
+OFP_BSN_PKTIN_FLAG_L3_MISS = 256
+OFP_BSN_PKTIN_FLAG_L3_CPU = 512
+OFP_BSN_PKTIN_FLAG_INGRESS_ACL = 1024
+OFP_BSN_PKTIN_FLAG_SFLOW = 2048
+OFP_BSN_PKTIN_FLAG_ARP_CACHE = 4096
+OFP_BSN_PKTIN_FLAG_ARP_TARGET = 8192
+
+ofp_bsn_pktin_flag_map = {
+    1: 'OFP_BSN_PKTIN_FLAG_PDU',
+    2: 'OFP_BSN_PKTIN_FLAG_NEW_HOST',
+    4: 'OFP_BSN_PKTIN_FLAG_STATION_MOVE',
+    8: 'OFP_BSN_PKTIN_FLAG_ARP',
+    16: 'OFP_BSN_PKTIN_FLAG_DHCP',
+    32: 'OFP_BSN_PKTIN_FLAG_L2_CPU',
+    64: 'OFP_BSN_PKTIN_FLAG_DEBUG',
+    128: 'OFP_BSN_PKTIN_FLAG_TTL_EXPIRED',
+    256: 'OFP_BSN_PKTIN_FLAG_L3_MISS',
+    512: 'OFP_BSN_PKTIN_FLAG_L3_CPU',
+    1024: 'OFP_BSN_PKTIN_FLAG_INGRESS_ACL',
+    2048: 'OFP_BSN_PKTIN_FLAG_SFLOW',
+    4096: 'OFP_BSN_PKTIN_FLAG_ARP_CACHE',
+    8192: 'OFP_BSN_PKTIN_FLAG_ARP_TARGET',
+}
+
+# Identifiers from group ofp_bsn_port_counter
+OFP_BSN_PORT_COUNTER_RX_BYTES = 0
+OFP_BSN_PORT_COUNTER_RX_PACKETS_UNICAST = 1
+OFP_BSN_PORT_COUNTER_RX_PACKETS_BROADCAST = 2
+OFP_BSN_PORT_COUNTER_RX_PACKETS_MULTICAST = 3
+OFP_BSN_PORT_COUNTER_RX_DROPPED = 4
+OFP_BSN_PORT_COUNTER_RX_ERRORS = 5
+OFP_BSN_PORT_COUNTER_TX_BYTES = 6
+OFP_BSN_PORT_COUNTER_TX_PACKETS_UNICAST = 7
+OFP_BSN_PORT_COUNTER_TX_PACKETS_BROADCAST = 8
+OFP_BSN_PORT_COUNTER_TX_PACKETS_MULTICAST = 9
+OFP_BSN_PORT_COUNTER_TX_DROPPED = 10
+OFP_BSN_PORT_COUNTER_TX_ERRORS = 11
+OFP_BSN_PORT_COUNTER_RX_RUNTS = 12
+OFP_BSN_PORT_COUNTER_RX_GIANTS = 13
+OFP_BSN_PORT_COUNTER_RX_CRC_ERRORS = 14
+OFP_BSN_PORT_COUNTER_RX_ALIGNMENT_ERRORS = 15
+OFP_BSN_PORT_COUNTER_RX_SYMBOL_ERRORS = 16
+OFP_BSN_PORT_COUNTER_RX_PAUSE_INPUT = 17
+OFP_BSN_PORT_COUNTER_TX_COLLISIONS = 18
+OFP_BSN_PORT_COUNTER_TX_LATE_COLLISIONS = 19
+OFP_BSN_PORT_COUNTER_TX_DEFERRED = 20
+OFP_BSN_PORT_COUNTER_TX_PAUSE_OUTPUT = 21
+OFP_BSN_PORT_COUNTER_RX_PACKETS = 22
+OFP_BSN_PORT_COUNTER_TX_PACKETS = 23
+OFP_BSN_PORT_COUNTER_RX_LENGTH_ERRORS = 24
+OFP_BSN_PORT_COUNTER_RX_OVERFLOW_ERRORS = 25
+OFP_BSN_PORT_COUNTER_TX_CARRIER_ERRORS = 26
+OFP_BSN_PORT_COUNTER_RX_PACKETS_BAD_VLAN = 27
+
+ofp_bsn_port_counter_map = {
+    0: 'OFP_BSN_PORT_COUNTER_RX_BYTES',
+    1: 'OFP_BSN_PORT_COUNTER_RX_PACKETS_UNICAST',
+    2: 'OFP_BSN_PORT_COUNTER_RX_PACKETS_BROADCAST',
+    3: 'OFP_BSN_PORT_COUNTER_RX_PACKETS_MULTICAST',
+    4: 'OFP_BSN_PORT_COUNTER_RX_DROPPED',
+    5: 'OFP_BSN_PORT_COUNTER_RX_ERRORS',
+    6: 'OFP_BSN_PORT_COUNTER_TX_BYTES',
+    7: 'OFP_BSN_PORT_COUNTER_TX_PACKETS_UNICAST',
+    8: 'OFP_BSN_PORT_COUNTER_TX_PACKETS_BROADCAST',
+    9: 'OFP_BSN_PORT_COUNTER_TX_PACKETS_MULTICAST',
+    10: 'OFP_BSN_PORT_COUNTER_TX_DROPPED',
+    11: 'OFP_BSN_PORT_COUNTER_TX_ERRORS',
+    12: 'OFP_BSN_PORT_COUNTER_RX_RUNTS',
+    13: 'OFP_BSN_PORT_COUNTER_RX_GIANTS',
+    14: 'OFP_BSN_PORT_COUNTER_RX_CRC_ERRORS',
+    15: 'OFP_BSN_PORT_COUNTER_RX_ALIGNMENT_ERRORS',
+    16: 'OFP_BSN_PORT_COUNTER_RX_SYMBOL_ERRORS',
+    17: 'OFP_BSN_PORT_COUNTER_RX_PAUSE_INPUT',
+    18: 'OFP_BSN_PORT_COUNTER_TX_COLLISIONS',
+    19: 'OFP_BSN_PORT_COUNTER_TX_LATE_COLLISIONS',
+    20: 'OFP_BSN_PORT_COUNTER_TX_DEFERRED',
+    21: 'OFP_BSN_PORT_COUNTER_TX_PAUSE_OUTPUT',
+    22: 'OFP_BSN_PORT_COUNTER_RX_PACKETS',
+    23: 'OFP_BSN_PORT_COUNTER_TX_PACKETS',
+    24: 'OFP_BSN_PORT_COUNTER_RX_LENGTH_ERRORS',
+    25: 'OFP_BSN_PORT_COUNTER_RX_OVERFLOW_ERRORS',
+    26: 'OFP_BSN_PORT_COUNTER_TX_CARRIER_ERRORS',
+    27: 'OFP_BSN_PORT_COUNTER_RX_PACKETS_BAD_VLAN',
+}
+
+# Identifiers from group ofp_bsn_tcp_flag
+OFP_BSN_TCP_FLAG_FIN = 1
+OFP_BSN_TCP_FLAG_SYN = 2
+OFP_BSN_TCP_FLAG_RST = 4
+OFP_BSN_TCP_FLAG_PSH = 8
+OFP_BSN_TCP_FLAG_ACK = 16
+OFP_BSN_TCP_FLAG_URG = 32
+OFP_BSN_TCP_FLAG_ECE = 64
+OFP_BSN_TCP_FLAG_CWR = 128
+OFP_BSN_TCP_FLAG_NS = 256
+
+ofp_bsn_tcp_flag_map = {
+    1: 'OFP_BSN_TCP_FLAG_FIN',
+    2: 'OFP_BSN_TCP_FLAG_SYN',
+    4: 'OFP_BSN_TCP_FLAG_RST',
+    8: 'OFP_BSN_TCP_FLAG_PSH',
+    16: 'OFP_BSN_TCP_FLAG_ACK',
+    32: 'OFP_BSN_TCP_FLAG_URG',
+    64: 'OFP_BSN_TCP_FLAG_ECE',
+    128: 'OFP_BSN_TCP_FLAG_CWR',
+    256: 'OFP_BSN_TCP_FLAG_NS',
+}
+
+# Identifiers from group ofp_bsn_udf_anchor
+OFP_BSN_UDF_ANCHOR_PACKET_START = 0
+OFP_BSN_UDF_ANCHOR_L3_HEADER_START = 1
+OFP_BSN_UDF_ANCHOR_L4_HEADER_START = 2
+
+ofp_bsn_udf_anchor_map = {
+    0: 'OFP_BSN_UDF_ANCHOR_PACKET_START',
+    1: 'OFP_BSN_UDF_ANCHOR_L3_HEADER_START',
+    2: 'OFP_BSN_UDF_ANCHOR_L4_HEADER_START',
+}
+
+# Identifiers from group ofp_bsn_vlan_counter_constants
+OFP_BSN_VLAN_ALL = 65535
+
+ofp_bsn_vlan_counter_constants_map = {
+    65535: 'OFP_BSN_VLAN_ALL',
+}
+
+# Identifiers from group ofp_bsn_vport_l2gre_flags
+OF_BSN_VPORT_L2GRE_LOCAL_MAC_IS_VALID = 1
+OF_BSN_VPORT_L2GRE_DSCP_ASSIGN = 2
+OF_BSN_VPORT_L2GRE_DSCP_COPY = 4
+OF_BSN_VPORT_L2GRE_LOOPBACK_IS_VALID = 8
+OF_BSN_VPORT_L2GRE_RATE_LIMIT_IS_VALID = 16
+
+ofp_bsn_vport_l2gre_flags_map = {
+    1: 'OF_BSN_VPORT_L2GRE_LOCAL_MAC_IS_VALID',
+    2: 'OF_BSN_VPORT_L2GRE_DSCP_ASSIGN',
+    4: 'OF_BSN_VPORT_L2GRE_DSCP_COPY',
+    8: 'OF_BSN_VPORT_L2GRE_LOOPBACK_IS_VALID',
+    16: 'OF_BSN_VPORT_L2GRE_RATE_LIMIT_IS_VALID',
+}
+
+# Identifiers from group ofp_bsn_vport_q_in_q_untagged
+OF_BSN_VPORT_Q_IN_Q_UNTAGGED = 65535
+
+ofp_bsn_vport_q_in_q_untagged_map = {
+    65535: 'OF_BSN_VPORT_Q_IN_Q_UNTAGGED',
+}
+
+# Identifiers from group ofp_bsn_vport_status
+OF_BSN_VPORT_STATUS_OK = 0
+OF_BSN_VPORT_STATUS_FAILED = 1
+
+ofp_bsn_vport_status_map = {
+    0: 'OF_BSN_VPORT_STATUS_OK',
+    1: 'OF_BSN_VPORT_STATUS_FAILED',
+}
+
+# Identifiers from group ofp_bsn_vrf_counter_constants
+OFP_BSN_VRF_ALL = 4294967295
+
+ofp_bsn_vrf_counter_constants_map = {
+    4294967295: 'OFP_BSN_VRF_ALL',
+}
+
+# Identifiers from group ofp_capabilities
+OFPC_FLOW_STATS = 1
+OFPC_TABLE_STATS = 2
+OFPC_PORT_STATS = 4
+OFPC_GROUP_STATS = 8
+OFPC_IP_REASM = 32
+OFPC_QUEUE_STATS = 64
+OFPC_PORT_BLOCKED = 256
+
+ofp_capabilities_map = {
+    1: 'OFPC_FLOW_STATS',
+    2: 'OFPC_TABLE_STATS',
+    4: 'OFPC_PORT_STATS',
+    8: 'OFPC_GROUP_STATS',
+    32: 'OFPC_IP_REASM',
+    64: 'OFPC_QUEUE_STATS',
+    256: 'OFPC_PORT_BLOCKED',
+}
+
+# Identifiers from group ofp_config_flags
+OFPC_FRAG_NORMAL = 0
+OFPC_FRAG_DROP = 1
+OFPC_FRAG_REASM = 2
+OFPC_FRAG_MASK = 3
+
+ofp_config_flags_map = {
+    0: 'OFPC_FRAG_NORMAL',
+    1: 'OFPC_FRAG_DROP',
+    2: 'OFPC_FRAG_REASM',
+    3: 'OFPC_FRAG_MASK',
+}
+
+# Identifiers from group ofp_controller_max_len
+OFPCML_MAX = 65509
+OFPCML_NO_BUFFER = 65535
+
+ofp_controller_max_len_map = {
+    65509: 'OFPCML_MAX',
+    65535: 'OFPCML_NO_BUFFER',
+}
+
+# Identifiers from group ofp_controller_role
+OFPCR_ROLE_NOCHANGE = 0
+OFPCR_ROLE_EQUAL = 1
+OFPCR_ROLE_MASTER = 2
+OFPCR_ROLE_SLAVE = 3
+
+ofp_controller_role_map = {
+    0: 'OFPCR_ROLE_NOCHANGE',
+    1: 'OFPCR_ROLE_EQUAL',
+    2: 'OFPCR_ROLE_MASTER',
+    3: 'OFPCR_ROLE_SLAVE',
+}
+
+# Identifiers from group ofp_error_type
+OFPET_HELLO_FAILED = 0
+OFPET_BAD_REQUEST = 1
+OFPET_BAD_ACTION = 2
+OFPET_BAD_INSTRUCTION = 3
+OFPET_BAD_MATCH = 4
+OFPET_FLOW_MOD_FAILED = 5
+OFPET_GROUP_MOD_FAILED = 6
+OFPET_PORT_MOD_FAILED = 7
+OFPET_TABLE_MOD_FAILED = 8
+OFPET_QUEUE_OP_FAILED = 9
+OFPET_SWITCH_CONFIG_FAILED = 10
+OFPET_ROLE_REQUEST_FAILED = 11
+OFPET_METER_MOD_FAILED = 12
+OFPET_TABLE_FEATURES_FAILED = 13
+OFPET_EXPERIMENTER = 65535
+
+ofp_error_type_map = {
+    0: 'OFPET_HELLO_FAILED',
+    1: 'OFPET_BAD_REQUEST',
+    2: 'OFPET_BAD_ACTION',
+    3: 'OFPET_BAD_INSTRUCTION',
+    4: 'OFPET_BAD_MATCH',
+    5: 'OFPET_FLOW_MOD_FAILED',
+    6: 'OFPET_GROUP_MOD_FAILED',
+    7: 'OFPET_PORT_MOD_FAILED',
+    8: 'OFPET_TABLE_MOD_FAILED',
+    9: 'OFPET_QUEUE_OP_FAILED',
+    10: 'OFPET_SWITCH_CONFIG_FAILED',
+    11: 'OFPET_ROLE_REQUEST_FAILED',
+    12: 'OFPET_METER_MOD_FAILED',
+    13: 'OFPET_TABLE_FEATURES_FAILED',
+    65535: 'OFPET_EXPERIMENTER',
+}
+
+# Identifiers from group ofp_flow_mod_command
+OFPFC_ADD = 0
+OFPFC_MODIFY = 1
+OFPFC_MODIFY_STRICT = 2
+OFPFC_DELETE = 3
+OFPFC_DELETE_STRICT = 4
+
+ofp_flow_mod_command_map = {
+    0: 'OFPFC_ADD',
+    1: 'OFPFC_MODIFY',
+    2: 'OFPFC_MODIFY_STRICT',
+    3: 'OFPFC_DELETE',
+    4: 'OFPFC_DELETE_STRICT',
+}
+
+# Identifiers from group ofp_flow_mod_failed_code
+OFPFMFC_UNKNOWN = 0
+OFPFMFC_TABLE_FULL = 1
+OFPFMFC_BAD_TABLE_ID = 2
+OFPFMFC_OVERLAP = 3
+OFPFMFC_EPERM = 4
+OFPFMFC_BAD_TIMEOUT = 5
+OFPFMFC_BAD_COMMAND = 6
+OFPFMFC_BAD_FLAGS = 7
+
+ofp_flow_mod_failed_code_map = {
+    0: 'OFPFMFC_UNKNOWN',
+    1: 'OFPFMFC_TABLE_FULL',
+    2: 'OFPFMFC_BAD_TABLE_ID',
+    3: 'OFPFMFC_OVERLAP',
+    4: 'OFPFMFC_EPERM',
+    5: 'OFPFMFC_BAD_TIMEOUT',
+    6: 'OFPFMFC_BAD_COMMAND',
+    7: 'OFPFMFC_BAD_FLAGS',
+}
+
+# Identifiers from group ofp_flow_mod_flags
+OFPFF_SEND_FLOW_REM = 1
+OFPFF_CHECK_OVERLAP = 2
+OFPFF_RESET_COUNTS = 4
+OFPFF_NO_PKT_COUNTS = 8
+OFPFF_NO_BYT_COUNTS = 16
+OFPFF_BSN_SEND_IDLE = 128
+
+ofp_flow_mod_flags_map = {
+    1: 'OFPFF_SEND_FLOW_REM',
+    2: 'OFPFF_CHECK_OVERLAP',
+    4: 'OFPFF_RESET_COUNTS',
+    8: 'OFPFF_NO_PKT_COUNTS',
+    16: 'OFPFF_NO_BYT_COUNTS',
+    128: 'OFPFF_BSN_SEND_IDLE',
+}
+
+# Identifiers from group ofp_flow_removed_reason
+OFPRR_IDLE_TIMEOUT = 0
+OFPRR_HARD_TIMEOUT = 1
+OFPRR_DELETE = 2
+OFPRR_GROUP_DELETE = 3
+
+ofp_flow_removed_reason_map = {
+    0: 'OFPRR_IDLE_TIMEOUT',
+    1: 'OFPRR_HARD_TIMEOUT',
+    2: 'OFPRR_DELETE',
+    3: 'OFPRR_GROUP_DELETE',
+}
+
+# Identifiers from group ofp_group
+OFPG_MAX = 4294967040
+OFPG_ALL = 4294967292
+OFPG_ANY = 4294967295
+
+ofp_group_map = {
+    4294967040: 'OFPG_MAX',
+    4294967292: 'OFPG_ALL',
+    4294967295: 'OFPG_ANY',
+}
+
+# Identifiers from group ofp_group_capabilities
+OFPGFC_SELECT_WEIGHT = 1
+OFPGFC_SELECT_LIVENESS = 2
+OFPGFC_CHAINING = 4
+OFPGFC_CHAINING_CHECKS = 8
+
+ofp_group_capabilities_map = {
+    1: 'OFPGFC_SELECT_WEIGHT',
+    2: 'OFPGFC_SELECT_LIVENESS',
+    4: 'OFPGFC_CHAINING',
+    8: 'OFPGFC_CHAINING_CHECKS',
+}
+
+# Identifiers from group ofp_group_mod_command
+OFPGC_ADD = 0
+OFPGC_MODIFY = 1
+OFPGC_DELETE = 2
+
+ofp_group_mod_command_map = {
+    0: 'OFPGC_ADD',
+    1: 'OFPGC_MODIFY',
+    2: 'OFPGC_DELETE',
+}
+
+# Identifiers from group ofp_group_mod_failed_code
+OFPGMFC_GROUP_EXISTS = 0
+OFPGMFC_INVALID_GROUP = 1
+OFPGMFC_WEIGHT_UNSUPPORTED = 2
+OFPGMFC_OUT_OF_GROUPS = 3
+OFPGMFC_OUT_OF_BUCKETS = 4
+OFPGMFC_CHAINING_UNSUPPORTED = 5
+OFPGMFC_WATCH_UNSUPPORTED = 6
+OFPGMFC_LOOP = 7
+OFPGMFC_UNKNOWN_GROUP = 8
+OFPGMFC_CHAINED_GROUP = 9
+OFPGMFC_BAD_TYPE = 10
+OFPGMFC_BAD_COMMAND = 11
+OFPGMFC_BAD_BUCKET = 12
+OFPGMFC_BAD_WATCH = 13
+OFPGMFC_EPERM = 14
+
+ofp_group_mod_failed_code_map = {
+    0: 'OFPGMFC_GROUP_EXISTS',
+    1: 'OFPGMFC_INVALID_GROUP',
+    2: 'OFPGMFC_WEIGHT_UNSUPPORTED',
+    3: 'OFPGMFC_OUT_OF_GROUPS',
+    4: 'OFPGMFC_OUT_OF_BUCKETS',
+    5: 'OFPGMFC_CHAINING_UNSUPPORTED',
+    6: 'OFPGMFC_WATCH_UNSUPPORTED',
+    7: 'OFPGMFC_LOOP',
+    8: 'OFPGMFC_UNKNOWN_GROUP',
+    9: 'OFPGMFC_CHAINED_GROUP',
+    10: 'OFPGMFC_BAD_TYPE',
+    11: 'OFPGMFC_BAD_COMMAND',
+    12: 'OFPGMFC_BAD_BUCKET',
+    13: 'OFPGMFC_BAD_WATCH',
+    14: 'OFPGMFC_EPERM',
+}
+
+# Identifiers from group ofp_group_type
+OFPGT_ALL = 0
+OFPGT_SELECT = 1
+OFPGT_INDIRECT = 2
+OFPGT_FF = 3
+
+ofp_group_type_map = {
+    0: 'OFPGT_ALL',
+    1: 'OFPGT_SELECT',
+    2: 'OFPGT_INDIRECT',
+    3: 'OFPGT_FF',
+}
+
+# Identifiers from group ofp_hello_elem_type
+OFPHET_VERSIONBITMAP = 1
+
+ofp_hello_elem_type_map = {
+    1: 'OFPHET_VERSIONBITMAP',
+}
+
+# Identifiers from group ofp_hello_failed_code
+OFPHFC_INCOMPATIBLE = 0
+OFPHFC_EPERM = 1
+
+ofp_hello_failed_code_map = {
+    0: 'OFPHFC_INCOMPATIBLE',
+    1: 'OFPHFC_EPERM',
+}
+
+# Identifiers from group ofp_instruction_type
+OFPIT_GOTO_TABLE = 1
+OFPIT_WRITE_METADATA = 2
+OFPIT_WRITE_ACTIONS = 3
+OFPIT_APPLY_ACTIONS = 4
+OFPIT_CLEAR_ACTIONS = 5
+OFPIT_METER = 6
+OFPIT_EXPERIMENTER = 65535
+
+ofp_instruction_type_map = {
+    1: 'OFPIT_GOTO_TABLE',
+    2: 'OFPIT_WRITE_METADATA',
+    3: 'OFPIT_WRITE_ACTIONS',
+    4: 'OFPIT_APPLY_ACTIONS',
+    5: 'OFPIT_CLEAR_ACTIONS',
+    6: 'OFPIT_METER',
+    65535: 'OFPIT_EXPERIMENTER',
+}
+
+# Identifiers from group ofp_ipv6exthdr_flags
+OFPIEH_NONEXT = 1
+OFPIEH_ESP = 2
+OFPIEH_AUTH = 4
+OFPIEH_DEST = 8
+OFPIEH_FRAG = 16
+OFPIEH_ROUTER = 32
+OFPIEH_HOP = 64
+OFPIEH_UNREP = 128
+OFPIEH_UNSEQ = 256
+
+ofp_ipv6exthdr_flags_map = {
+    1: 'OFPIEH_NONEXT',
+    2: 'OFPIEH_ESP',
+    4: 'OFPIEH_AUTH',
+    8: 'OFPIEH_DEST',
+    16: 'OFPIEH_FRAG',
+    32: 'OFPIEH_ROUTER',
+    64: 'OFPIEH_HOP',
+    128: 'OFPIEH_UNREP',
+    256: 'OFPIEH_UNSEQ',
+}
+
+# Identifiers from group ofp_match_type
+OFPMT_STANDARD = 0
+OFPMT_OXM = 1
+
+ofp_match_type_map = {
+    0: 'OFPMT_STANDARD',
+    1: 'OFPMT_OXM',
+}
+
+# Identifiers from group ofp_meter
+OFPM_MAX = 4294901760
+OFPM_SLOWPATH = 4294967293
+OFPM_CONTROLLER = 4294967294
+OFPM_ALL = 4294967295
+
+ofp_meter_map = {
+    4294901760: 'OFPM_MAX',
+    4294967293: 'OFPM_SLOWPATH',
+    4294967294: 'OFPM_CONTROLLER',
+    4294967295: 'OFPM_ALL',
+}
+
+# Identifiers from group ofp_meter_band_type
+OFPMBT_DROP = 1
+OFPMBT_DSCP_REMARK = 2
+OFPMBT_EXPERIMENTER = 65535
+
+ofp_meter_band_type_map = {
+    1: 'OFPMBT_DROP',
+    2: 'OFPMBT_DSCP_REMARK',
+    65535: 'OFPMBT_EXPERIMENTER',
+}
+
+# Identifiers from group ofp_meter_flags
+OFPMF_KBPS = 1
+OFPMF_PKTPS = 2
+OFPMF_BURST = 4
+OFPMF_STATS = 8
+
+ofp_meter_flags_map = {
+    1: 'OFPMF_KBPS',
+    2: 'OFPMF_PKTPS',
+    4: 'OFPMF_BURST',
+    8: 'OFPMF_STATS',
+}
+
+# Identifiers from group ofp_meter_mod_command
+OFPMC_ADD = 0
+OFPMC_MODIFY = 1
+OFPMC_DELETE = 2
+
+ofp_meter_mod_command_map = {
+    0: 'OFPMC_ADD',
+    1: 'OFPMC_MODIFY',
+    2: 'OFPMC_DELETE',
+}
+
+# Identifiers from group ofp_meter_mod_failed_code
+OFPMMFC_UNKNOWN = 0
+OFPMMFC_METER_EXISTS = 1
+OFPMMFC_INVALID_METER = 2
+OFPMMFC_UNKNOWN_METER = 3
+OFPMMFC_BAD_COMMAND = 4
+OFPMMFC_BAD_FLAGS = 5
+OFPMMFC_BAD_RATE = 6
+OFPMMFC_BAD_BURST = 7
+OFPMMFC_BAD_BAND = 8
+OFPMMFC_BAD_BAND_VALUE = 9
+OFPMMFC_OUT_OF_METERS = 10
+OFPMMFC_OUT_OF_BANDS = 11
+
+ofp_meter_mod_failed_code_map = {
+    0: 'OFPMMFC_UNKNOWN',
+    1: 'OFPMMFC_METER_EXISTS',
+    2: 'OFPMMFC_INVALID_METER',
+    3: 'OFPMMFC_UNKNOWN_METER',
+    4: 'OFPMMFC_BAD_COMMAND',
+    5: 'OFPMMFC_BAD_FLAGS',
+    6: 'OFPMMFC_BAD_RATE',
+    7: 'OFPMMFC_BAD_BURST',
+    8: 'OFPMMFC_BAD_BAND',
+    9: 'OFPMMFC_BAD_BAND_VALUE',
+    10: 'OFPMMFC_OUT_OF_METERS',
+    11: 'OFPMMFC_OUT_OF_BANDS',
+}
+
+# Identifiers from group ofp_oxm_class
+OFPXMC_NXM_0 = 0
+OFPXMC_NXM_1 = 1
+OFPXMC_OPENFLOW_BASIC = 32768
+OFPXMC_EXPERIMENTER = 65535
+
+ofp_oxm_class_map = {
+    0: 'OFPXMC_NXM_0',
+    1: 'OFPXMC_NXM_1',
+    32768: 'OFPXMC_OPENFLOW_BASIC',
+    65535: 'OFPXMC_EXPERIMENTER',
+}
+
+# Identifiers from group ofp_packet_in_reason
+OFPR_NO_MATCH = 0
+OFPR_ACTION = 1
+OFPR_INVALID_TTL = 2
+OFPR_BSN_NEW_HOST = 128
+OFPR_BSN_STATION_MOVE = 129
+OFPR_BSN_BAD_VLAN = 130
+OFPR_BSN_DESTINATION_LOOKUP_FAILURE = 131
+OFPR_BSN_NO_ROUTE = 132
+OFPR_BSN_ICMP_ECHO_REQUEST = 133
+OFPR_BSN_DEST_NETWORK_UNREACHABLE = 134
+OFPR_BSN_DEST_HOST_UNREACHABLE = 135
+OFPR_BSN_DEST_PORT_UNREACHABLE = 136
+OFPR_BSN_FRAGMENTATION_REQUIRED = 137
+OFPR_BSN_ARP = 139
+OFPR_BSN_DHCP = 140
+OFPR_BSN_DEBUG = 141
+OFPR_BSN_PACKET_OF_DEATH = 142
+
+ofp_packet_in_reason_map = {
+    0: 'OFPR_NO_MATCH',
+    1: 'OFPR_ACTION',
+    2: 'OFPR_INVALID_TTL',
+    128: 'OFPR_BSN_NEW_HOST',
+    129: 'OFPR_BSN_STATION_MOVE',
+    130: 'OFPR_BSN_BAD_VLAN',
+    131: 'OFPR_BSN_DESTINATION_LOOKUP_FAILURE',
+    132: 'OFPR_BSN_NO_ROUTE',
+    133: 'OFPR_BSN_ICMP_ECHO_REQUEST',
+    134: 'OFPR_BSN_DEST_NETWORK_UNREACHABLE',
+    135: 'OFPR_BSN_DEST_HOST_UNREACHABLE',
+    136: 'OFPR_BSN_DEST_PORT_UNREACHABLE',
+    137: 'OFPR_BSN_FRAGMENTATION_REQUIRED',
+    139: 'OFPR_BSN_ARP',
+    140: 'OFPR_BSN_DHCP',
+    141: 'OFPR_BSN_DEBUG',
+    142: 'OFPR_BSN_PACKET_OF_DEATH',
+}
+
+# Identifiers from group ofp_port
+OFPP_MAX = 4294967040
+OFPP_IN_PORT = 4294967288
+OFPP_TABLE = 4294967289
+OFPP_NORMAL = 4294967290
+OFPP_FLOOD = 4294967291
+OFPP_ALL = 4294967292
+OFPP_CONTROLLER = 4294967293
+OFPP_LOCAL = 4294967294
+OFPP_ANY = 4294967295
+
+ofp_port_map = {
+    4294967040: 'OFPP_MAX',
+    4294967288: 'OFPP_IN_PORT',
+    4294967289: 'OFPP_TABLE',
+    4294967290: 'OFPP_NORMAL',
+    4294967291: 'OFPP_FLOOD',
+    4294967292: 'OFPP_ALL',
+    4294967293: 'OFPP_CONTROLLER',
+    4294967294: 'OFPP_LOCAL',
+    4294967295: 'OFPP_ANY',
+}
+
+# Identifiers from group ofp_port_config
+OFPPC_PORT_DOWN = 1
+OFPPC_NO_RECV = 4
+OFPPC_NO_FWD = 32
+OFPPC_NO_PACKET_IN = 64
+OFPPC_BSN_MIRROR_DEST = 2147483648
+
+ofp_port_config_map = {
+    1: 'OFPPC_PORT_DOWN',
+    4: 'OFPPC_NO_RECV',
+    32: 'OFPPC_NO_FWD',
+    64: 'OFPPC_NO_PACKET_IN',
+    2147483648: 'OFPPC_BSN_MIRROR_DEST',
+}
+
+# Identifiers from group ofp_port_features
+OFPPF_10MB_HD = 1
+OFPPF_10MB_FD = 2
+OFPPF_100MB_HD = 4
+OFPPF_100MB_FD = 8
+OFPPF_1GB_HD = 16
+OFPPF_1GB_FD = 32
+OFPPF_10GB_FD = 64
+OFPPF_40GB_FD = 128
+OFPPF_100GB_FD = 256
+OFPPF_1TB_FD = 512
+OFPPF_OTHER = 1024
+OFPPF_COPPER = 2048
+OFPPF_FIBER = 4096
+OFPPF_AUTONEG = 8192
+OFPPF_PAUSE = 16384
+OFPPF_PAUSE_ASYM = 32768
+OFPPF_BSN_BREAKOUT_CAPABLE = 2147483648
+
+ofp_port_features_map = {
+    1: 'OFPPF_10MB_HD',
+    2: 'OFPPF_10MB_FD',
+    4: 'OFPPF_100MB_HD',
+    8: 'OFPPF_100MB_FD',
+    16: 'OFPPF_1GB_HD',
+    32: 'OFPPF_1GB_FD',
+    64: 'OFPPF_10GB_FD',
+    128: 'OFPPF_40GB_FD',
+    256: 'OFPPF_100GB_FD',
+    512: 'OFPPF_1TB_FD',
+    1024: 'OFPPF_OTHER',
+    2048: 'OFPPF_COPPER',
+    4096: 'OFPPF_FIBER',
+    8192: 'OFPPF_AUTONEG',
+    16384: 'OFPPF_PAUSE',
+    32768: 'OFPPF_PAUSE_ASYM',
+    2147483648: 'OFPPF_BSN_BREAKOUT_CAPABLE',
+}
+
+# Identifiers from group ofp_port_mod_failed_code
+OFPPMFC_BAD_PORT = 0
+OFPPMFC_BAD_HW_ADDR = 1
+OFPPMFC_BAD_CONFIG = 2
+OFPPMFC_BAD_ADVERTISE = 3
+OFPPMFC_EPERM = 4
+
+ofp_port_mod_failed_code_map = {
+    0: 'OFPPMFC_BAD_PORT',
+    1: 'OFPPMFC_BAD_HW_ADDR',
+    2: 'OFPPMFC_BAD_CONFIG',
+    3: 'OFPPMFC_BAD_ADVERTISE',
+    4: 'OFPPMFC_EPERM',
+}
+
+# Identifiers from group ofp_port_reason
+OFPPR_ADD = 0
+OFPPR_DELETE = 1
+OFPPR_MODIFY = 2
+
+ofp_port_reason_map = {
+    0: 'OFPPR_ADD',
+    1: 'OFPPR_DELETE',
+    2: 'OFPPR_MODIFY',
+}
+
+# Identifiers from group ofp_port_state
+OFPPS_LINK_DOWN = 1
+OFPPS_BLOCKED = 2
+OFPPS_LIVE = 4
+
+ofp_port_state_map = {
+    1: 'OFPPS_LINK_DOWN',
+    2: 'OFPPS_BLOCKED',
+    4: 'OFPPS_LIVE',
+}
+
+# Identifiers from group ofp_queue_op_failed_code
+OFPQOFC_BAD_PORT = 0
+OFPQOFC_BAD_QUEUE = 1
+OFPQOFC_EPERM = 2
+
+ofp_queue_op_failed_code_map = {
+    0: 'OFPQOFC_BAD_PORT',
+    1: 'OFPQOFC_BAD_QUEUE',
+    2: 'OFPQOFC_EPERM',
+}
+
+# Identifiers from group ofp_queue_properties
+OFPQT_MIN_RATE = 1
+OFPQT_MAX_RATE = 2
+OFPQT_EXPERIMENTER = 65535
+
+ofp_queue_properties_map = {
+    1: 'OFPQT_MIN_RATE',
+    2: 'OFPQT_MAX_RATE',
+    65535: 'OFPQT_EXPERIMENTER',
+}
+
+# Identifiers from group ofp_role_request_failed_code
+OFPRRFC_STALE = 0
+OFPRRFC_UNSUP = 1
+OFPRRFC_BAD_ROLE = 2
+
+ofp_role_request_failed_code_map = {
+    0: 'OFPRRFC_STALE',
+    1: 'OFPRRFC_UNSUP',
+    2: 'OFPRRFC_BAD_ROLE',
+}
+
+# Identifiers from group ofp_stats_reply_flags
+OFPSF_REPLY_MORE = 1
+
+ofp_stats_reply_flags_map = {
+    1: 'OFPSF_REPLY_MORE',
+}
+
+# Identifiers from group ofp_stats_request_flags
+OFPSF_REQ_MORE = 1
+
+ofp_stats_request_flags_map = {
+    1: 'OFPSF_REQ_MORE',
+}
+
+# Identifiers from group ofp_stats_type
+OFPST_DESC = 0
+OFPST_FLOW = 1
+OFPST_AGGREGATE = 2
+OFPST_TABLE = 3
+OFPST_PORT = 4
+OFPST_QUEUE = 5
+OFPST_GROUP = 6
+OFPST_GROUP_DESC = 7
+OFPST_GROUP_FEATURES = 8
+OFPST_METER = 9
+OFPST_METER_CONFIG = 10
+OFPST_METER_FEATURES = 11
+OFPST_TABLE_FEATURES = 12
+OFPST_PORT_DESC = 13
+OFPST_EXPERIMENTER = 65535
+
+ofp_stats_type_map = {
+    0: 'OFPST_DESC',
+    1: 'OFPST_FLOW',
+    2: 'OFPST_AGGREGATE',
+    3: 'OFPST_TABLE',
+    4: 'OFPST_PORT',
+    5: 'OFPST_QUEUE',
+    6: 'OFPST_GROUP',
+    7: 'OFPST_GROUP_DESC',
+    8: 'OFPST_GROUP_FEATURES',
+    9: 'OFPST_METER',
+    10: 'OFPST_METER_CONFIG',
+    11: 'OFPST_METER_FEATURES',
+    12: 'OFPST_TABLE_FEATURES',
+    13: 'OFPST_PORT_DESC',
+    65535: 'OFPST_EXPERIMENTER',
+}
+
+# Identifiers from group ofp_switch_config_failed_code
+OFPSCFC_BAD_FLAGS = 0
+OFPSCFC_BAD_LEN = 1
+OFPSCFC_EPERM = 2
+
+ofp_switch_config_failed_code_map = {
+    0: 'OFPSCFC_BAD_FLAGS',
+    1: 'OFPSCFC_BAD_LEN',
+    2: 'OFPSCFC_EPERM',
+}
+
+# Identifiers from group ofp_table
+OFPTT_MAX = 254
+OFPTT_ALL = 255
+
+ofp_table_map = {
+    254: 'OFPTT_MAX',
+    255: 'OFPTT_ALL',
+}
+
+# Identifiers from group ofp_table_config
+OFPTC_DEPRECATED_MASK = 3
+
+ofp_table_config_map = {
+    3: 'OFPTC_DEPRECATED_MASK',
+}
+
+# Identifiers from group ofp_table_feature_prop_type
+OFPTFPT_INSTRUCTIONS = 0
+OFPTFPT_INSTRUCTIONS_MISS = 1
+OFPTFPT_NEXT_TABLES = 2
+OFPTFPT_NEXT_TABLES_MISS = 3
+OFPTFPT_WRITE_ACTIONS = 4
+OFPTFPT_WRITE_ACTIONS_MISS = 5
+OFPTFPT_APPLY_ACTIONS = 6
+OFPTFPT_APPLY_ACTIONS_MISS = 7
+OFPTFPT_MATCH = 8
+OFPTFPT_WILDCARDS = 10
+OFPTFPT_WRITE_SETFIELD = 12
+OFPTFPT_WRITE_SETFIELD_MISS = 13
+OFPTFPT_APPLY_SETFIELD = 14
+OFPTFPT_APPLY_SETFIELD_MISS = 15
+OFPTFPT_EXPERIMENTER = 65534
+OFPTFPT_EXPERIMENTER_MISS = 65535
+
+ofp_table_feature_prop_type_map = {
+    0: 'OFPTFPT_INSTRUCTIONS',
+    1: 'OFPTFPT_INSTRUCTIONS_MISS',
+    2: 'OFPTFPT_NEXT_TABLES',
+    3: 'OFPTFPT_NEXT_TABLES_MISS',
+    4: 'OFPTFPT_WRITE_ACTIONS',
+    5: 'OFPTFPT_WRITE_ACTIONS_MISS',
+    6: 'OFPTFPT_APPLY_ACTIONS',
+    7: 'OFPTFPT_APPLY_ACTIONS_MISS',
+    8: 'OFPTFPT_MATCH',
+    10: 'OFPTFPT_WILDCARDS',
+    12: 'OFPTFPT_WRITE_SETFIELD',
+    13: 'OFPTFPT_WRITE_SETFIELD_MISS',
+    14: 'OFPTFPT_APPLY_SETFIELD',
+    15: 'OFPTFPT_APPLY_SETFIELD_MISS',
+    65534: 'OFPTFPT_EXPERIMENTER',
+    65535: 'OFPTFPT_EXPERIMENTER_MISS',
+}
+
+# Identifiers from group ofp_table_features_failed_code
+OFPTFFC_BAD_TABLE = 0
+OFPTFFC_BAD_METADATA = 1
+OFPTFFC_BAD_TYPE = 2
+OFPTFFC_BAD_LEN = 3
+OFPTFFC_BAD_ARGUMENT = 4
+OFPTFFC_EPERM = 5
+
+ofp_table_features_failed_code_map = {
+    0: 'OFPTFFC_BAD_TABLE',
+    1: 'OFPTFFC_BAD_METADATA',
+    2: 'OFPTFFC_BAD_TYPE',
+    3: 'OFPTFFC_BAD_LEN',
+    4: 'OFPTFFC_BAD_ARGUMENT',
+    5: 'OFPTFFC_EPERM',
+}
+
+# Identifiers from group ofp_table_mod_failed_code
+OFPTMFC_BAD_TABLE = 0
+OFPTMFC_BAD_CONFIG = 1
+OFPTMFC_EPERM = 2
+
+ofp_table_mod_failed_code_map = {
+    0: 'OFPTMFC_BAD_TABLE',
+    1: 'OFPTMFC_BAD_CONFIG',
+    2: 'OFPTMFC_EPERM',
+}
+
+# Identifiers from group ofp_type
+OFPT_HELLO = 0
+OFPT_ERROR = 1
+OFPT_ECHO_REQUEST = 2
+OFPT_ECHO_REPLY = 3
+OFPT_EXPERIMENTER = 4
+OFPT_FEATURES_REQUEST = 5
+OFPT_FEATURES_REPLY = 6
+OFPT_GET_CONFIG_REQUEST = 7
+OFPT_GET_CONFIG_REPLY = 8
+OFPT_SET_CONFIG = 9
+OFPT_PACKET_IN = 10
+OFPT_FLOW_REMOVED = 11
+OFPT_PORT_STATUS = 12
+OFPT_PACKET_OUT = 13
+OFPT_FLOW_MOD = 14
+OFPT_GROUP_MOD = 15
+OFPT_PORT_MOD = 16
+OFPT_TABLE_MOD = 17
+OFPT_STATS_REQUEST = 18
+OFPT_STATS_REPLY = 19
+OFPT_BARRIER_REQUEST = 20
+OFPT_BARRIER_REPLY = 21
+OFPT_QUEUE_GET_CONFIG_REQUEST = 22
+OFPT_QUEUE_GET_CONFIG_REPLY = 23
+OFPT_ROLE_REQUEST = 24
+OFPT_ROLE_REPLY = 25
+OFPT_GET_ASYNC_REQUEST = 26
+OFPT_GET_ASYNC_REPLY = 27
+OFPT_SET_ASYNC = 28
+OFPT_METER_MOD = 29
+
+ofp_type_map = {
+    0: 'OFPT_HELLO',
+    1: 'OFPT_ERROR',
+    2: 'OFPT_ECHO_REQUEST',
+    3: 'OFPT_ECHO_REPLY',
+    4: 'OFPT_EXPERIMENTER',
+    5: 'OFPT_FEATURES_REQUEST',
+    6: 'OFPT_FEATURES_REPLY',
+    7: 'OFPT_GET_CONFIG_REQUEST',
+    8: 'OFPT_GET_CONFIG_REPLY',
+    9: 'OFPT_SET_CONFIG',
+    10: 'OFPT_PACKET_IN',
+    11: 'OFPT_FLOW_REMOVED',
+    12: 'OFPT_PORT_STATUS',
+    13: 'OFPT_PACKET_OUT',
+    14: 'OFPT_FLOW_MOD',
+    15: 'OFPT_GROUP_MOD',
+    16: 'OFPT_PORT_MOD',
+    17: 'OFPT_TABLE_MOD',
+    18: 'OFPT_STATS_REQUEST',
+    19: 'OFPT_STATS_REPLY',
+    20: 'OFPT_BARRIER_REQUEST',
+    21: 'OFPT_BARRIER_REPLY',
+    22: 'OFPT_QUEUE_GET_CONFIG_REQUEST',
+    23: 'OFPT_QUEUE_GET_CONFIG_REPLY',
+    24: 'OFPT_ROLE_REQUEST',
+    25: 'OFPT_ROLE_REPLY',
+    26: 'OFPT_GET_ASYNC_REQUEST',
+    27: 'OFPT_GET_ASYNC_REPLY',
+    28: 'OFPT_SET_ASYNC',
+    29: 'OFPT_METER_MOD',
+}
+
+# Identifiers from group ofp_vlan_id
+OFPVID_NONE = 0
+OFPVID_PRESENT = 4096
+
+ofp_vlan_id_map = {
+    0: 'OFPVID_NONE',
+    4096: 'OFPVID_PRESENT',
+}
+
diff --git a/Fabric/Utilities/src/python/loxi/of13/instruction.py b/Fabric/Utilities/src/python/loxi/of13/instruction.py
new file mode 100644
index 0000000..7bf9b62
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of13/instruction.py
@@ -0,0 +1,1171 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of13']
+
+class instruction(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = instruction.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = instruction()
+        obj.type = reader.read("!H")[0]
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("instruction {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class apply_actions(instruction):
+    type = 4
+
+    def __init__(self, actions=None):
+        if actions != None:
+            self.actions = actions
+        else:
+            self.actions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.actions))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = apply_actions()
+        _type = reader.read("!H")[0]
+        assert(_type == 4)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        obj.actions = loxi.generic_util.unpack_list(reader, ofp.action.action.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.actions != other.actions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("apply_actions {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("actions = ");
+                q.pp(self.actions)
+            q.breakable()
+        q.text('}')
+
+instruction.subtypes[4] = apply_actions
+
+class experimenter(instruction):
+    subtypes = {}
+
+    type = 65535
+
+    def __init__(self, experimenter=None, data=None):
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 4)
+        subclass = experimenter.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = experimenter()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.experimenter = reader.read("!L")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.experimenter != other.experimenter: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+instruction.subtypes[65535] = experimenter
+
+class bsn(experimenter):
+    subtypes = {}
+
+    type = 65535
+    experimenter = 6035143
+
+    def __init__(self, subtype=None):
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 8)
+        subclass = bsn.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = bsn()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        obj.subtype = reader.read("!L")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+experimenter.subtypes[6035143] = bsn
+
+class bsn_arp_offload(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 1
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_arp_offload()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 1)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_arp_offload {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[1] = bsn_arp_offload
+
+class bsn_auto_negotiation(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 11
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_auto_negotiation()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 11)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_auto_negotiation {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[11] = bsn_auto_negotiation
+
+class bsn_deny(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 5
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_deny()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 5)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_deny {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[5] = bsn_deny
+
+class bsn_dhcp_offload(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 2
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_dhcp_offload()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 2)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_dhcp_offload {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[2] = bsn_dhcp_offload
+
+class bsn_disable_l3(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 13
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_disable_l3()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 13)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_disable_l3 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[13] = bsn_disable_l3
+
+class bsn_disable_split_horizon_check(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 3
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_disable_split_horizon_check()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 3)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_disable_split_horizon_check {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[3] = bsn_disable_split_horizon_check
+
+class bsn_disable_src_mac_check(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 0
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_disable_src_mac_check()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 0)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_disable_src_mac_check {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[0] = bsn_disable_src_mac_check
+
+class bsn_disable_vlan_counters(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 9
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_disable_vlan_counters()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 9)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_disable_vlan_counters {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[9] = bsn_disable_vlan_counters
+
+class bsn_internal_priority(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 12
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_internal_priority()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 12)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_internal_priority {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[12] = bsn_internal_priority
+
+class bsn_packet_of_death(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 6
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_packet_of_death()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 6)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_packet_of_death {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[6] = bsn_packet_of_death
+
+class bsn_permit(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 4
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_permit()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_permit {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[4] = bsn_permit
+
+class bsn_prioritize_pdus(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 7
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_prioritize_pdus()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 7)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_prioritize_pdus {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[7] = bsn_prioritize_pdus
+
+class bsn_require_vlan_xlate(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 8
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_require_vlan_xlate()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 8)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_require_vlan_xlate {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[8] = bsn_require_vlan_xlate
+
+class bsn_span_destination(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 10
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_span_destination()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 10)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_span_destination {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[10] = bsn_span_destination
+
+class clear_actions(instruction):
+    type = 5
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = clear_actions()
+        _type = reader.read("!H")[0]
+        assert(_type == 5)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("clear_actions {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+instruction.subtypes[5] = clear_actions
+
+class goto_table(instruction):
+    type = 1
+
+    def __init__(self, table_id=None):
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = goto_table()
+        _type = reader.read("!H")[0]
+        assert(_type == 1)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.table_id = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.table_id != other.table_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("goto_table {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+            q.breakable()
+        q.text('}')
+
+instruction.subtypes[1] = goto_table
+
+class meter(instruction):
+    type = 6
+
+    def __init__(self, meter_id=None):
+        if meter_id != None:
+            self.meter_id = meter_id
+        else:
+            self.meter_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.meter_id))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = meter()
+        _type = reader.read("!H")[0]
+        assert(_type == 6)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.meter_id = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.meter_id != other.meter_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("meter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("meter_id = ");
+                q.text("%#x" % self.meter_id)
+            q.breakable()
+        q.text('}')
+
+instruction.subtypes[6] = meter
+
+class write_actions(instruction):
+    type = 3
+
+    def __init__(self, actions=None):
+        if actions != None:
+            self.actions = actions
+        else:
+            self.actions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.actions))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = write_actions()
+        _type = reader.read("!H")[0]
+        assert(_type == 3)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        obj.actions = loxi.generic_util.unpack_list(reader, ofp.action.action.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.actions != other.actions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("write_actions {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("actions = ");
+                q.pp(self.actions)
+            q.breakable()
+        q.text('}')
+
+instruction.subtypes[3] = write_actions
+
+class write_metadata(instruction):
+    type = 2
+
+    def __init__(self, metadata=None, metadata_mask=None):
+        if metadata != None:
+            self.metadata = metadata
+        else:
+            self.metadata = 0
+        if metadata_mask != None:
+            self.metadata_mask = metadata_mask
+        else:
+            self.metadata_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!Q", self.metadata))
+        packed.append(struct.pack("!Q", self.metadata_mask))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = write_metadata()
+        _type = reader.read("!H")[0]
+        assert(_type == 2)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        obj.metadata = reader.read("!Q")[0]
+        obj.metadata_mask = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.metadata != other.metadata: return False
+        if self.metadata_mask != other.metadata_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("write_metadata {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("metadata = ");
+                q.text("%#x" % self.metadata)
+                q.text(","); q.breakable()
+                q.text("metadata_mask = ");
+                q.text("%#x" % self.metadata_mask)
+            q.breakable()
+        q.text('}')
+
+instruction.subtypes[2] = write_metadata
+
+
diff --git a/Fabric/Utilities/src/python/loxi/of13/instruction_id.py b/Fabric/Utilities/src/python/loxi/of13/instruction_id.py
new file mode 100644
index 0000000..67b6506
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of13/instruction_id.py
@@ -0,0 +1,1060 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of13']
+
+class instruction_id(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = instruction_id.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = instruction_id()
+        obj.type = reader.read("!H")[0]
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("instruction_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class apply_actions(instruction_id):
+    type = 4
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = apply_actions()
+        _type = reader.read("!H")[0]
+        assert(_type == 4)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("apply_actions {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+instruction_id.subtypes[4] = apply_actions
+
+class experimenter(instruction_id):
+    subtypes = {}
+
+    type = 65535
+
+    def __init__(self, experimenter=None):
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 4)
+        subclass = experimenter.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = experimenter()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.experimenter = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.experimenter != other.experimenter: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+instruction_id.subtypes[65535] = experimenter
+
+class bsn(experimenter):
+    subtypes = {}
+
+    type = 65535
+    experimenter = 6035143
+
+    def __init__(self, subtype=None):
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 8)
+        subclass = bsn.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = bsn()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        obj.subtype = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+experimenter.subtypes[6035143] = bsn
+
+class bsn_arp_offload(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 1
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_arp_offload()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 1)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_arp_offload {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[1] = bsn_arp_offload
+
+class bsn_auto_negotiation(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 11
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_auto_negotiation()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 11)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_auto_negotiation {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[11] = bsn_auto_negotiation
+
+class bsn_deny(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 5
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_deny()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 5)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_deny {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[5] = bsn_deny
+
+class bsn_dhcp_offload(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 2
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_dhcp_offload()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 2)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_dhcp_offload {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[2] = bsn_dhcp_offload
+
+class bsn_disable_l3(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 13
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_disable_l3()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 13)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_disable_l3 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[13] = bsn_disable_l3
+
+class bsn_disable_split_horizon_check(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 3
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_disable_split_horizon_check()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_disable_split_horizon_check {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[3] = bsn_disable_split_horizon_check
+
+class bsn_disable_src_mac_check(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 0
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_disable_src_mac_check()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 0)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_disable_src_mac_check {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[0] = bsn_disable_src_mac_check
+
+class bsn_disable_vlan_counters(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 9
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_disable_vlan_counters()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 9)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_disable_vlan_counters {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[9] = bsn_disable_vlan_counters
+
+class bsn_internal_priority(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 12
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_internal_priority()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 12)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_internal_priority {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[12] = bsn_internal_priority
+
+class bsn_packet_of_death(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 6
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_packet_of_death()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 6)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_packet_of_death {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[6] = bsn_packet_of_death
+
+class bsn_permit(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 4
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_permit()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_permit {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[4] = bsn_permit
+
+class bsn_prioritize_pdus(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 7
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_prioritize_pdus()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 7)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_prioritize_pdus {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[7] = bsn_prioritize_pdus
+
+class bsn_require_vlan_xlate(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 8
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_require_vlan_xlate()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 8)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_require_vlan_xlate {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[8] = bsn_require_vlan_xlate
+
+class bsn_span_destination(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 10
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_span_destination()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 10)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_span_destination {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[10] = bsn_span_destination
+
+class clear_actions(instruction_id):
+    type = 5
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = clear_actions()
+        _type = reader.read("!H")[0]
+        assert(_type == 5)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("clear_actions {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+instruction_id.subtypes[5] = clear_actions
+
+class goto_table(instruction_id):
+    type = 1
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = goto_table()
+        _type = reader.read("!H")[0]
+        assert(_type == 1)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("goto_table {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+instruction_id.subtypes[1] = goto_table
+
+class meter(instruction_id):
+    type = 6
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = meter()
+        _type = reader.read("!H")[0]
+        assert(_type == 6)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("meter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+instruction_id.subtypes[6] = meter
+
+class write_actions(instruction_id):
+    type = 3
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = write_actions()
+        _type = reader.read("!H")[0]
+        assert(_type == 3)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("write_actions {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+instruction_id.subtypes[3] = write_actions
+
+class write_metadata(instruction_id):
+    type = 2
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = write_metadata()
+        _type = reader.read("!H")[0]
+        assert(_type == 2)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("write_metadata {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+instruction_id.subtypes[2] = write_metadata
+
+
diff --git a/Fabric/Utilities/src/python/loxi/of13/message.py b/Fabric/Utilities/src/python/loxi/of13/message.py
new file mode 100644
index 0000000..c9f27e6
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of13/message.py
@@ -0,0 +1,15224 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of13']
+
+class message(loxi.OFObject):
+    subtypes = {}
+
+    version = 4
+
+    def __init__(self, type=None, xid=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('B', 1)
+        subclass = message.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = message()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        obj.type = reader.read("!B")[0]
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("message {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+
+class stats_reply(message):
+    subtypes = {}
+
+    version = 4
+    type = 19
+
+    def __init__(self, xid=None, stats_type=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if stats_type != None:
+            self.stats_type = stats_type
+        else:
+            self.stats_type = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 8)
+        subclass = stats_reply.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.stats_type = reader.read("!H")[0]
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.stats_type != other.stats_type: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[19] = stats_reply
+
+class aggregate_stats_reply(stats_reply):
+    version = 4
+    type = 19
+    stats_type = 2
+
+    def __init__(self, xid=None, flags=None, packet_count=None, byte_count=None, flow_count=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if packet_count != None:
+            self.packet_count = packet_count
+        else:
+            self.packet_count = 0
+        if byte_count != None:
+            self.byte_count = byte_count
+        else:
+            self.byte_count = 0
+        if flow_count != None:
+            self.flow_count = flow_count
+        else:
+            self.flow_count = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!Q", self.packet_count))
+        packed.append(struct.pack("!Q", self.byte_count))
+        packed.append(struct.pack("!L", self.flow_count))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = aggregate_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 2)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.packet_count = reader.read("!Q")[0]
+        obj.byte_count = reader.read("!Q")[0]
+        obj.flow_count = reader.read("!L")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.packet_count != other.packet_count: return False
+        if self.byte_count != other.byte_count: return False
+        if self.flow_count != other.flow_count: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("aggregate_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("packet_count = ");
+                q.text("%#x" % self.packet_count)
+                q.text(","); q.breakable()
+                q.text("byte_count = ");
+                q.text("%#x" % self.byte_count)
+                q.text(","); q.breakable()
+                q.text("flow_count = ");
+                q.text("%#x" % self.flow_count)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[2] = aggregate_stats_reply
+
+class stats_request(message):
+    subtypes = {}
+
+    version = 4
+    type = 18
+
+    def __init__(self, xid=None, stats_type=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if stats_type != None:
+            self.stats_type = stats_type
+        else:
+            self.stats_type = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 8)
+        subclass = stats_request.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.stats_type = reader.read("!H")[0]
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.stats_type != other.stats_type: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[18] = stats_request
+
+class aggregate_stats_request(stats_request):
+    version = 4
+    type = 18
+    stats_type = 2
+
+    def __init__(self, xid=None, flags=None, table_id=None, out_port=None, out_group=None, cookie=None, cookie_mask=None, match=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if out_group != None:
+            self.out_group = out_group
+        else:
+            self.out_group = 0
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if cookie_mask != None:
+            self.cookie_mask = cookie_mask
+        else:
+            self.cookie_mask = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append('\x00' * 3)
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!L", self.out_group))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.cookie_mask))
+        packed.append(self.match.pack())
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = aggregate_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 2)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.table_id = reader.read("!B")[0]
+        reader.skip(3)
+        obj.out_port = util.unpack_port_no(reader)
+        obj.out_group = reader.read("!L")[0]
+        reader.skip(4)
+        obj.cookie = reader.read("!Q")[0]
+        obj.cookie_mask = reader.read("!Q")[0]
+        obj.match = ofp.match.unpack(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.table_id != other.table_id: return False
+        if self.out_port != other.out_port: return False
+        if self.out_group != other.out_group: return False
+        if self.cookie != other.cookie: return False
+        if self.cookie_mask != other.cookie_mask: return False
+        if self.match != other.match: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("aggregate_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("out_group = ");
+                q.text("%#x" % self.out_group)
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("cookie_mask = ");
+                q.text("%#x" % self.cookie_mask)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[2] = aggregate_stats_request
+
+class async_get_reply(message):
+    version = 4
+    type = 27
+
+    def __init__(self, xid=None, packet_in_mask_equal_master=None, packet_in_mask_slave=None, port_status_mask_equal_master=None, port_status_mask_slave=None, flow_removed_mask_equal_master=None, flow_removed_mask_slave=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if packet_in_mask_equal_master != None:
+            self.packet_in_mask_equal_master = packet_in_mask_equal_master
+        else:
+            self.packet_in_mask_equal_master = 0
+        if packet_in_mask_slave != None:
+            self.packet_in_mask_slave = packet_in_mask_slave
+        else:
+            self.packet_in_mask_slave = 0
+        if port_status_mask_equal_master != None:
+            self.port_status_mask_equal_master = port_status_mask_equal_master
+        else:
+            self.port_status_mask_equal_master = 0
+        if port_status_mask_slave != None:
+            self.port_status_mask_slave = port_status_mask_slave
+        else:
+            self.port_status_mask_slave = 0
+        if flow_removed_mask_equal_master != None:
+            self.flow_removed_mask_equal_master = flow_removed_mask_equal_master
+        else:
+            self.flow_removed_mask_equal_master = 0
+        if flow_removed_mask_slave != None:
+            self.flow_removed_mask_slave = flow_removed_mask_slave
+        else:
+            self.flow_removed_mask_slave = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.packet_in_mask_equal_master))
+        packed.append(struct.pack("!L", self.packet_in_mask_slave))
+        packed.append(struct.pack("!L", self.port_status_mask_equal_master))
+        packed.append(struct.pack("!L", self.port_status_mask_slave))
+        packed.append(struct.pack("!L", self.flow_removed_mask_equal_master))
+        packed.append(struct.pack("!L", self.flow_removed_mask_slave))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = async_get_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 27)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.packet_in_mask_equal_master = reader.read("!L")[0]
+        obj.packet_in_mask_slave = reader.read("!L")[0]
+        obj.port_status_mask_equal_master = reader.read("!L")[0]
+        obj.port_status_mask_slave = reader.read("!L")[0]
+        obj.flow_removed_mask_equal_master = reader.read("!L")[0]
+        obj.flow_removed_mask_slave = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.packet_in_mask_equal_master != other.packet_in_mask_equal_master: return False
+        if self.packet_in_mask_slave != other.packet_in_mask_slave: return False
+        if self.port_status_mask_equal_master != other.port_status_mask_equal_master: return False
+        if self.port_status_mask_slave != other.port_status_mask_slave: return False
+        if self.flow_removed_mask_equal_master != other.flow_removed_mask_equal_master: return False
+        if self.flow_removed_mask_slave != other.flow_removed_mask_slave: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("async_get_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("packet_in_mask_equal_master = ");
+                q.text("%#x" % self.packet_in_mask_equal_master)
+                q.text(","); q.breakable()
+                q.text("packet_in_mask_slave = ");
+                q.text("%#x" % self.packet_in_mask_slave)
+                q.text(","); q.breakable()
+                q.text("port_status_mask_equal_master = ");
+                q.text("%#x" % self.port_status_mask_equal_master)
+                q.text(","); q.breakable()
+                q.text("port_status_mask_slave = ");
+                q.text("%#x" % self.port_status_mask_slave)
+                q.text(","); q.breakable()
+                q.text("flow_removed_mask_equal_master = ");
+                q.text("%#x" % self.flow_removed_mask_equal_master)
+                q.text(","); q.breakable()
+                q.text("flow_removed_mask_slave = ");
+                q.text("%#x" % self.flow_removed_mask_slave)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[27] = async_get_reply
+
+class async_get_request(message):
+    version = 4
+    type = 26
+
+    def __init__(self, xid=None, packet_in_mask_equal_master=None, packet_in_mask_slave=None, port_status_mask_equal_master=None, port_status_mask_slave=None, flow_removed_mask_equal_master=None, flow_removed_mask_slave=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if packet_in_mask_equal_master != None:
+            self.packet_in_mask_equal_master = packet_in_mask_equal_master
+        else:
+            self.packet_in_mask_equal_master = 0
+        if packet_in_mask_slave != None:
+            self.packet_in_mask_slave = packet_in_mask_slave
+        else:
+            self.packet_in_mask_slave = 0
+        if port_status_mask_equal_master != None:
+            self.port_status_mask_equal_master = port_status_mask_equal_master
+        else:
+            self.port_status_mask_equal_master = 0
+        if port_status_mask_slave != None:
+            self.port_status_mask_slave = port_status_mask_slave
+        else:
+            self.port_status_mask_slave = 0
+        if flow_removed_mask_equal_master != None:
+            self.flow_removed_mask_equal_master = flow_removed_mask_equal_master
+        else:
+            self.flow_removed_mask_equal_master = 0
+        if flow_removed_mask_slave != None:
+            self.flow_removed_mask_slave = flow_removed_mask_slave
+        else:
+            self.flow_removed_mask_slave = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.packet_in_mask_equal_master))
+        packed.append(struct.pack("!L", self.packet_in_mask_slave))
+        packed.append(struct.pack("!L", self.port_status_mask_equal_master))
+        packed.append(struct.pack("!L", self.port_status_mask_slave))
+        packed.append(struct.pack("!L", self.flow_removed_mask_equal_master))
+        packed.append(struct.pack("!L", self.flow_removed_mask_slave))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = async_get_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 26)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.packet_in_mask_equal_master = reader.read("!L")[0]
+        obj.packet_in_mask_slave = reader.read("!L")[0]
+        obj.port_status_mask_equal_master = reader.read("!L")[0]
+        obj.port_status_mask_slave = reader.read("!L")[0]
+        obj.flow_removed_mask_equal_master = reader.read("!L")[0]
+        obj.flow_removed_mask_slave = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.packet_in_mask_equal_master != other.packet_in_mask_equal_master: return False
+        if self.packet_in_mask_slave != other.packet_in_mask_slave: return False
+        if self.port_status_mask_equal_master != other.port_status_mask_equal_master: return False
+        if self.port_status_mask_slave != other.port_status_mask_slave: return False
+        if self.flow_removed_mask_equal_master != other.flow_removed_mask_equal_master: return False
+        if self.flow_removed_mask_slave != other.flow_removed_mask_slave: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("async_get_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("packet_in_mask_equal_master = ");
+                q.text("%#x" % self.packet_in_mask_equal_master)
+                q.text(","); q.breakable()
+                q.text("packet_in_mask_slave = ");
+                q.text("%#x" % self.packet_in_mask_slave)
+                q.text(","); q.breakable()
+                q.text("port_status_mask_equal_master = ");
+                q.text("%#x" % self.port_status_mask_equal_master)
+                q.text(","); q.breakable()
+                q.text("port_status_mask_slave = ");
+                q.text("%#x" % self.port_status_mask_slave)
+                q.text(","); q.breakable()
+                q.text("flow_removed_mask_equal_master = ");
+                q.text("%#x" % self.flow_removed_mask_equal_master)
+                q.text(","); q.breakable()
+                q.text("flow_removed_mask_slave = ");
+                q.text("%#x" % self.flow_removed_mask_slave)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[26] = async_get_request
+
+class async_set(message):
+    version = 4
+    type = 28
+
+    def __init__(self, xid=None, packet_in_mask_equal_master=None, packet_in_mask_slave=None, port_status_mask_equal_master=None, port_status_mask_slave=None, flow_removed_mask_equal_master=None, flow_removed_mask_slave=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if packet_in_mask_equal_master != None:
+            self.packet_in_mask_equal_master = packet_in_mask_equal_master
+        else:
+            self.packet_in_mask_equal_master = 0
+        if packet_in_mask_slave != None:
+            self.packet_in_mask_slave = packet_in_mask_slave
+        else:
+            self.packet_in_mask_slave = 0
+        if port_status_mask_equal_master != None:
+            self.port_status_mask_equal_master = port_status_mask_equal_master
+        else:
+            self.port_status_mask_equal_master = 0
+        if port_status_mask_slave != None:
+            self.port_status_mask_slave = port_status_mask_slave
+        else:
+            self.port_status_mask_slave = 0
+        if flow_removed_mask_equal_master != None:
+            self.flow_removed_mask_equal_master = flow_removed_mask_equal_master
+        else:
+            self.flow_removed_mask_equal_master = 0
+        if flow_removed_mask_slave != None:
+            self.flow_removed_mask_slave = flow_removed_mask_slave
+        else:
+            self.flow_removed_mask_slave = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.packet_in_mask_equal_master))
+        packed.append(struct.pack("!L", self.packet_in_mask_slave))
+        packed.append(struct.pack("!L", self.port_status_mask_equal_master))
+        packed.append(struct.pack("!L", self.port_status_mask_slave))
+        packed.append(struct.pack("!L", self.flow_removed_mask_equal_master))
+        packed.append(struct.pack("!L", self.flow_removed_mask_slave))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = async_set()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 28)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.packet_in_mask_equal_master = reader.read("!L")[0]
+        obj.packet_in_mask_slave = reader.read("!L")[0]
+        obj.port_status_mask_equal_master = reader.read("!L")[0]
+        obj.port_status_mask_slave = reader.read("!L")[0]
+        obj.flow_removed_mask_equal_master = reader.read("!L")[0]
+        obj.flow_removed_mask_slave = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.packet_in_mask_equal_master != other.packet_in_mask_equal_master: return False
+        if self.packet_in_mask_slave != other.packet_in_mask_slave: return False
+        if self.port_status_mask_equal_master != other.port_status_mask_equal_master: return False
+        if self.port_status_mask_slave != other.port_status_mask_slave: return False
+        if self.flow_removed_mask_equal_master != other.flow_removed_mask_equal_master: return False
+        if self.flow_removed_mask_slave != other.flow_removed_mask_slave: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("async_set {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("packet_in_mask_equal_master = ");
+                q.text("%#x" % self.packet_in_mask_equal_master)
+                q.text(","); q.breakable()
+                q.text("packet_in_mask_slave = ");
+                q.text("%#x" % self.packet_in_mask_slave)
+                q.text(","); q.breakable()
+                q.text("port_status_mask_equal_master = ");
+                q.text("%#x" % self.port_status_mask_equal_master)
+                q.text(","); q.breakable()
+                q.text("port_status_mask_slave = ");
+                q.text("%#x" % self.port_status_mask_slave)
+                q.text(","); q.breakable()
+                q.text("flow_removed_mask_equal_master = ");
+                q.text("%#x" % self.flow_removed_mask_equal_master)
+                q.text(","); q.breakable()
+                q.text("flow_removed_mask_slave = ");
+                q.text("%#x" % self.flow_removed_mask_slave)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[28] = async_set
+
+class error_msg(message):
+    subtypes = {}
+
+    version = 4
+    type = 1
+
+    def __init__(self, xid=None, err_type=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if err_type != None:
+            self.err_type = err_type
+        else:
+            self.err_type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 8)
+        subclass = error_msg.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.err_type = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.err_type != other.err_type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+message.subtypes[1] = error_msg
+
+class bad_action_error_msg(error_msg):
+    version = 4
+    type = 1
+    err_type = 2
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bad_action_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 2)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bad_action_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[2] = bad_action_error_msg
+
+class bad_instruction_error_msg(error_msg):
+    version = 4
+    type = 1
+    err_type = 3
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bad_instruction_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 3)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bad_instruction_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[3] = bad_instruction_error_msg
+
+class bad_match_error_msg(error_msg):
+    version = 4
+    type = 1
+    err_type = 4
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bad_match_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 4)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bad_match_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[4] = bad_match_error_msg
+
+class bad_request_error_msg(error_msg):
+    version = 4
+    type = 1
+    err_type = 1
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bad_request_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 1)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bad_request_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[1] = bad_request_error_msg
+
+class barrier_reply(message):
+    version = 4
+    type = 21
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = barrier_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 21)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("barrier_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+message.subtypes[21] = barrier_reply
+
+class barrier_request(message):
+    version = 4
+    type = 20
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = barrier_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 20)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("barrier_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+message.subtypes[20] = barrier_request
+
+class experimenter(message):
+    subtypes = {}
+
+    version = 4
+    type = 4
+
+    def __init__(self, xid=None, experimenter=None, subtype=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 8)
+        subclass = experimenter.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = experimenter()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.experimenter = reader.read("!L")[0]
+        obj.subtype = reader.read("!L")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.experimenter != other.experimenter: return False
+        if self.subtype != other.subtype: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("subtype = ");
+                q.text("%#x" % self.subtype)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[4] = experimenter
+
+class bsn_header(experimenter):
+    subtypes = {}
+
+    version = 4
+    type = 4
+    experimenter = 6035143
+
+    def __init__(self, xid=None, subtype=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 12)
+        subclass = bsn_header.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = bsn_header()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        obj.subtype = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_header {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+experimenter.subtypes[6035143] = bsn_header
+
+class bsn_arp_idle(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 60
+
+    def __init__(self, xid=None, vlan_vid=None, ipv4_addr=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if vlan_vid != None:
+            self.vlan_vid = vlan_vid
+        else:
+            self.vlan_vid = 0
+        if ipv4_addr != None:
+            self.ipv4_addr = ipv4_addr
+        else:
+            self.ipv4_addr = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!H", self.vlan_vid))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!L", self.ipv4_addr))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_arp_idle()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 60)
+        obj.vlan_vid = reader.read("!H")[0]
+        reader.skip(2)
+        obj.ipv4_addr = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.vlan_vid != other.vlan_vid: return False
+        if self.ipv4_addr != other.ipv4_addr: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_arp_idle {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("vlan_vid = ");
+                q.text("%#x" % self.vlan_vid)
+                q.text(","); q.breakable()
+                q.text("ipv4_addr = ");
+                q.text(util.pretty_ipv4(self.ipv4_addr))
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[60] = bsn_arp_idle
+
+class bsn_bw_clear_data_reply(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 22
+
+    def __init__(self, xid=None, status=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.status))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_bw_clear_data_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 22)
+        obj.status = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.status != other.status: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_bw_clear_data_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[22] = bsn_bw_clear_data_reply
+
+class bsn_bw_clear_data_request(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 21
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_bw_clear_data_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 21)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_bw_clear_data_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[21] = bsn_bw_clear_data_request
+
+class bsn_bw_enable_get_reply(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 20
+
+    def __init__(self, xid=None, enabled=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if enabled != None:
+            self.enabled = enabled
+        else:
+            self.enabled = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.enabled))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_bw_enable_get_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 20)
+        obj.enabled = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.enabled != other.enabled: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_bw_enable_get_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("enabled = ");
+                q.text("%#x" % self.enabled)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[20] = bsn_bw_enable_get_reply
+
+class bsn_bw_enable_get_request(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 19
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_bw_enable_get_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 19)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_bw_enable_get_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[19] = bsn_bw_enable_get_request
+
+class bsn_bw_enable_set_reply(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 23
+
+    def __init__(self, xid=None, enable=None, status=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if enable != None:
+            self.enable = enable
+        else:
+            self.enable = 0
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.enable))
+        packed.append(struct.pack("!L", self.status))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_bw_enable_set_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 23)
+        obj.enable = reader.read("!L")[0]
+        obj.status = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.enable != other.enable: return False
+        if self.status != other.status: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_bw_enable_set_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("enable = ");
+                q.text("%#x" % self.enable)
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[23] = bsn_bw_enable_set_reply
+
+class bsn_bw_enable_set_request(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 18
+
+    def __init__(self, xid=None, enable=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if enable != None:
+            self.enable = enable
+        else:
+            self.enable = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.enable))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_bw_enable_set_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 18)
+        obj.enable = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.enable != other.enable: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_bw_enable_set_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("enable = ");
+                q.text("%#x" % self.enable)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[18] = bsn_bw_enable_set_request
+
+class bsn_controller_connections_reply(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 57
+
+    def __init__(self, xid=None, connections=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if connections != None:
+            self.connections = connections
+        else:
+            self.connections = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.connections))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_controller_connections_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 57)
+        obj.connections = loxi.generic_util.unpack_list(reader, ofp.common.bsn_controller_connection.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.connections != other.connections: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_controller_connections_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("connections = ");
+                q.pp(self.connections)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[57] = bsn_controller_connections_reply
+
+class bsn_controller_connections_request(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 56
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_controller_connections_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 56)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_controller_connections_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[56] = bsn_controller_connections_request
+
+class experimenter_stats_reply(stats_reply):
+    subtypes = {}
+
+    version = 4
+    type = 19
+    stats_type = 65535
+
+    def __init__(self, xid=None, flags=None, experimenter=None, subtype=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 16)
+        subclass = experimenter_stats_reply.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = experimenter_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.experimenter = reader.read("!L")[0]
+        obj.subtype = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.experimenter != other.experimenter: return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("subtype = ");
+                q.text("%#x" % self.subtype)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[65535] = experimenter_stats_reply
+
+class bsn_stats_reply(experimenter_stats_reply):
+    subtypes = {}
+
+    version = 4
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+
+    def __init__(self, xid=None, flags=None, subtype=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 20)
+        subclass = bsn_stats_reply.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = bsn_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        obj.subtype = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+experimenter_stats_reply.subtypes[6035143] = bsn_stats_reply
+
+class bsn_debug_counter_desc_stats_reply(bsn_stats_reply):
+    version = 4
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 13
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_debug_counter_desc_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 13)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.bsn_debug_counter_desc_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_debug_counter_desc_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_reply.subtypes[13] = bsn_debug_counter_desc_stats_reply
+
+class experimenter_stats_request(stats_request):
+    subtypes = {}
+
+    version = 4
+    type = 18
+    stats_type = 65535
+
+    def __init__(self, xid=None, flags=None, experimenter=None, subtype=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 16)
+        subclass = experimenter_stats_request.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = experimenter_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.experimenter = reader.read("!L")[0]
+        obj.subtype = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.experimenter != other.experimenter: return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("subtype = ");
+                q.text("%#x" % self.subtype)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[65535] = experimenter_stats_request
+
+class bsn_stats_request(experimenter_stats_request):
+    subtypes = {}
+
+    version = 4
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+
+    def __init__(self, xid=None, flags=None, subtype=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 20)
+        subclass = bsn_stats_request.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = bsn_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        obj.subtype = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+experimenter_stats_request.subtypes[6035143] = bsn_stats_request
+
+class bsn_debug_counter_desc_stats_request(bsn_stats_request):
+    version = 4
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 13
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_debug_counter_desc_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 13)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_debug_counter_desc_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_request.subtypes[13] = bsn_debug_counter_desc_stats_request
+
+class bsn_debug_counter_stats_reply(bsn_stats_reply):
+    version = 4
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 12
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_debug_counter_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 12)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.bsn_debug_counter_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_debug_counter_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_reply.subtypes[12] = bsn_debug_counter_stats_reply
+
+class bsn_debug_counter_stats_request(bsn_stats_request):
+    version = 4
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 12
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_debug_counter_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 12)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_debug_counter_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_request.subtypes[12] = bsn_debug_counter_stats_request
+
+class bsn_flow_checksum_bucket_stats_reply(bsn_stats_reply):
+    version = 4
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 10
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_flow_checksum_bucket_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 10)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.bsn_flow_checksum_bucket_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_flow_checksum_bucket_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_reply.subtypes[10] = bsn_flow_checksum_bucket_stats_reply
+
+class bsn_flow_checksum_bucket_stats_request(bsn_stats_request):
+    version = 4
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 10
+
+    def __init__(self, xid=None, flags=None, table_id=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!B", self.table_id))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_flow_checksum_bucket_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 10)
+        obj.table_id = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.table_id != other.table_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_flow_checksum_bucket_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_request.subtypes[10] = bsn_flow_checksum_bucket_stats_request
+
+class bsn_flow_idle(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 40
+
+    def __init__(self, xid=None, cookie=None, priority=None, table_id=None, match=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append('\x00' * 5)
+        packed.append(self.match.pack())
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_flow_idle()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 40)
+        obj.cookie = reader.read("!Q")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.table_id = reader.read("!B")[0]
+        reader.skip(5)
+        obj.match = ofp.match.unpack(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.cookie != other.cookie: return False
+        if self.priority != other.priority: return False
+        if self.table_id != other.table_id: return False
+        if self.match != other.match: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_flow_idle {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[40] = bsn_flow_idle
+
+class bsn_flow_idle_enable_get_reply(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 39
+
+    def __init__(self, xid=None, enabled=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if enabled != None:
+            self.enabled = enabled
+        else:
+            self.enabled = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.enabled))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_flow_idle_enable_get_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 39)
+        obj.enabled = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.enabled != other.enabled: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_flow_idle_enable_get_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("enabled = ");
+                q.text("%#x" % self.enabled)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[39] = bsn_flow_idle_enable_get_reply
+
+class bsn_flow_idle_enable_get_request(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 38
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_flow_idle_enable_get_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 38)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_flow_idle_enable_get_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[38] = bsn_flow_idle_enable_get_request
+
+class bsn_flow_idle_enable_set_reply(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 37
+
+    def __init__(self, xid=None, enable=None, status=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if enable != None:
+            self.enable = enable
+        else:
+            self.enable = 0
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.enable))
+        packed.append(struct.pack("!L", self.status))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_flow_idle_enable_set_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 37)
+        obj.enable = reader.read("!L")[0]
+        obj.status = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.enable != other.enable: return False
+        if self.status != other.status: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_flow_idle_enable_set_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("enable = ");
+                q.text("%#x" % self.enable)
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[37] = bsn_flow_idle_enable_set_reply
+
+class bsn_flow_idle_enable_set_request(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 36
+
+    def __init__(self, xid=None, enable=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if enable != None:
+            self.enable = enable
+        else:
+            self.enable = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.enable))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_flow_idle_enable_set_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 36)
+        obj.enable = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.enable != other.enable: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_flow_idle_enable_set_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("enable = ");
+                q.text("%#x" % self.enable)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[36] = bsn_flow_idle_enable_set_request
+
+class bsn_generic_stats_reply(bsn_stats_reply):
+    version = 4
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 16
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_generic_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 16)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.bsn_generic_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_generic_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_reply.subtypes[16] = bsn_generic_stats_reply
+
+class bsn_generic_stats_request(bsn_stats_request):
+    version = 4
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 16
+
+    def __init__(self, xid=None, flags=None, name=None, tlvs=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if name != None:
+            self.name = name
+        else:
+            self.name = ""
+        if tlvs != None:
+            self.tlvs = tlvs
+        else:
+            self.tlvs = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!64s", self.name))
+        packed.append(loxi.generic_util.pack_list(self.tlvs))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_generic_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 16)
+        obj.name = reader.read("!64s")[0].rstrip("\x00")
+        obj.tlvs = loxi.generic_util.unpack_list(reader, ofp.bsn_tlv.bsn_tlv.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.name != other.name: return False
+        if self.tlvs != other.tlvs: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_generic_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("name = ");
+                q.pp(self.name)
+                q.text(","); q.breakable()
+                q.text("tlvs = ");
+                q.pp(self.tlvs)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_request.subtypes[16] = bsn_generic_stats_request
+
+class bsn_gentable_bucket_stats_reply(bsn_stats_reply):
+    version = 4
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 5
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_bucket_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 5)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.bsn_gentable_bucket_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_bucket_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_reply.subtypes[5] = bsn_gentable_bucket_stats_reply
+
+class bsn_gentable_bucket_stats_request(bsn_stats_request):
+    version = 4
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 5
+
+    def __init__(self, xid=None, flags=None, table_id=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!H", self.table_id))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_bucket_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 5)
+        obj.table_id = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.table_id != other.table_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_bucket_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_request.subtypes[5] = bsn_gentable_bucket_stats_request
+
+class bsn_gentable_clear_reply(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 49
+
+    def __init__(self, xid=None, table_id=None, deleted_count=None, error_count=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if deleted_count != None:
+            self.deleted_count = deleted_count
+        else:
+            self.deleted_count = 0
+        if error_count != None:
+            self.error_count = error_count
+        else:
+            self.error_count = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!H", self.table_id))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!L", self.deleted_count))
+        packed.append(struct.pack("!L", self.error_count))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_clear_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 49)
+        obj.table_id = reader.read("!H")[0]
+        reader.skip(2)
+        obj.deleted_count = reader.read("!L")[0]
+        obj.error_count = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.table_id != other.table_id: return False
+        if self.deleted_count != other.deleted_count: return False
+        if self.error_count != other.error_count: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_clear_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("deleted_count = ");
+                q.text("%#x" % self.deleted_count)
+                q.text(","); q.breakable()
+                q.text("error_count = ");
+                q.text("%#x" % self.error_count)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[49] = bsn_gentable_clear_reply
+
+class bsn_gentable_clear_request(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 48
+
+    def __init__(self, xid=None, table_id=None, checksum=None, checksum_mask=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if checksum != None:
+            self.checksum = checksum
+        else:
+            self.checksum = 0
+        if checksum_mask != None:
+            self.checksum_mask = checksum_mask
+        else:
+            self.checksum_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!H", self.table_id))
+        packed.append('\x00' * 2)
+        packed.append(util.pack_checksum_128(self.checksum))
+        packed.append(util.pack_checksum_128(self.checksum_mask))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_clear_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 48)
+        obj.table_id = reader.read("!H")[0]
+        reader.skip(2)
+        obj.checksum = util.unpack_checksum_128(reader)
+        obj.checksum_mask = util.unpack_checksum_128(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.table_id != other.table_id: return False
+        if self.checksum != other.checksum: return False
+        if self.checksum_mask != other.checksum_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_clear_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("checksum = ");
+                q.pp(self.checksum)
+                q.text(","); q.breakable()
+                q.text("checksum_mask = ");
+                q.pp(self.checksum_mask)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[48] = bsn_gentable_clear_request
+
+class bsn_gentable_desc_stats_reply(bsn_stats_reply):
+    version = 4
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 4
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_desc_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.bsn_gentable_desc_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_desc_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_reply.subtypes[4] = bsn_gentable_desc_stats_reply
+
+class bsn_gentable_desc_stats_request(bsn_stats_request):
+    version = 4
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 4
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_desc_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_desc_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_request.subtypes[4] = bsn_gentable_desc_stats_request
+
+class bsn_gentable_entry_add(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 46
+
+    def __init__(self, xid=None, table_id=None, checksum=None, key=None, value=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if checksum != None:
+            self.checksum = checksum
+        else:
+            self.checksum = 0
+        if key != None:
+            self.key = key
+        else:
+            self.key = []
+        if value != None:
+            self.value = value
+        else:
+            self.value = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!H", self.table_id))
+        packed.append(struct.pack("!H", 0)) # placeholder for key_length at index 7
+        packed.append(util.pack_checksum_128(self.checksum))
+        packed.append(loxi.generic_util.pack_list(self.key))
+        packed[7] = struct.pack("!H", len(packed[-1]))
+        packed.append(loxi.generic_util.pack_list(self.value))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_entry_add()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 46)
+        obj.table_id = reader.read("!H")[0]
+        _key_length = reader.read("!H")[0]
+        obj.checksum = util.unpack_checksum_128(reader)
+        obj.key = loxi.generic_util.unpack_list(reader.slice(_key_length), ofp.bsn_tlv.bsn_tlv.unpack)
+        obj.value = loxi.generic_util.unpack_list(reader, ofp.bsn_tlv.bsn_tlv.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.table_id != other.table_id: return False
+        if self.checksum != other.checksum: return False
+        if self.key != other.key: return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_entry_add {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("checksum = ");
+                q.pp(self.checksum)
+                q.text(","); q.breakable()
+                q.text("key = ");
+                q.pp(self.key)
+                q.text(","); q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[46] = bsn_gentable_entry_add
+
+class bsn_gentable_entry_delete(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 47
+
+    def __init__(self, xid=None, table_id=None, key=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if key != None:
+            self.key = key
+        else:
+            self.key = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!H", self.table_id))
+        packed.append(loxi.generic_util.pack_list(self.key))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_entry_delete()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 47)
+        obj.table_id = reader.read("!H")[0]
+        obj.key = loxi.generic_util.unpack_list(reader, ofp.bsn_tlv.bsn_tlv.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.table_id != other.table_id: return False
+        if self.key != other.key: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_entry_delete {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("key = ");
+                q.pp(self.key)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[47] = bsn_gentable_entry_delete
+
+class bsn_gentable_entry_desc_stats_reply(bsn_stats_reply):
+    version = 4
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 2
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_entry_desc_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 2)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.bsn_gentable_entry_desc_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_entry_desc_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_reply.subtypes[2] = bsn_gentable_entry_desc_stats_reply
+
+class bsn_gentable_entry_desc_stats_request(bsn_stats_request):
+    version = 4
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 2
+
+    def __init__(self, xid=None, flags=None, table_id=None, checksum=None, checksum_mask=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if checksum != None:
+            self.checksum = checksum
+        else:
+            self.checksum = 0
+        if checksum_mask != None:
+            self.checksum_mask = checksum_mask
+        else:
+            self.checksum_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!H", self.table_id))
+        packed.append('\x00' * 2)
+        packed.append(util.pack_checksum_128(self.checksum))
+        packed.append(util.pack_checksum_128(self.checksum_mask))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_entry_desc_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 2)
+        obj.table_id = reader.read("!H")[0]
+        reader.skip(2)
+        obj.checksum = util.unpack_checksum_128(reader)
+        obj.checksum_mask = util.unpack_checksum_128(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.table_id != other.table_id: return False
+        if self.checksum != other.checksum: return False
+        if self.checksum_mask != other.checksum_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_entry_desc_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("checksum = ");
+                q.pp(self.checksum)
+                q.text(","); q.breakable()
+                q.text("checksum_mask = ");
+                q.pp(self.checksum_mask)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_request.subtypes[2] = bsn_gentable_entry_desc_stats_request
+
+class bsn_gentable_entry_stats_reply(bsn_stats_reply):
+    version = 4
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 3
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_entry_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 3)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.bsn_gentable_entry_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_entry_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_reply.subtypes[3] = bsn_gentable_entry_stats_reply
+
+class bsn_gentable_entry_stats_request(bsn_stats_request):
+    version = 4
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 3
+
+    def __init__(self, xid=None, flags=None, table_id=None, checksum=None, checksum_mask=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if checksum != None:
+            self.checksum = checksum
+        else:
+            self.checksum = 0
+        if checksum_mask != None:
+            self.checksum_mask = checksum_mask
+        else:
+            self.checksum_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!H", self.table_id))
+        packed.append('\x00' * 2)
+        packed.append(util.pack_checksum_128(self.checksum))
+        packed.append(util.pack_checksum_128(self.checksum_mask))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_entry_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 3)
+        obj.table_id = reader.read("!H")[0]
+        reader.skip(2)
+        obj.checksum = util.unpack_checksum_128(reader)
+        obj.checksum_mask = util.unpack_checksum_128(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.table_id != other.table_id: return False
+        if self.checksum != other.checksum: return False
+        if self.checksum_mask != other.checksum_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_entry_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("checksum = ");
+                q.pp(self.checksum)
+                q.text(","); q.breakable()
+                q.text("checksum_mask = ");
+                q.pp(self.checksum_mask)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_request.subtypes[3] = bsn_gentable_entry_stats_request
+
+class bsn_gentable_set_buckets_size(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 50
+
+    def __init__(self, xid=None, table_id=None, buckets_size=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if buckets_size != None:
+            self.buckets_size = buckets_size
+        else:
+            self.buckets_size = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!H", self.table_id))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!L", self.buckets_size))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_set_buckets_size()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 50)
+        obj.table_id = reader.read("!H")[0]
+        reader.skip(2)
+        obj.buckets_size = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.table_id != other.table_id: return False
+        if self.buckets_size != other.buckets_size: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_set_buckets_size {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("buckets_size = ");
+                q.text("%#x" % self.buckets_size)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[50] = bsn_gentable_set_buckets_size
+
+class bsn_gentable_stats_reply(bsn_stats_reply):
+    version = 4
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 7
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 7)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.bsn_gentable_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_reply.subtypes[7] = bsn_gentable_stats_reply
+
+class bsn_gentable_stats_request(bsn_stats_request):
+    version = 4
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 7
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 7)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_request.subtypes[7] = bsn_gentable_stats_request
+
+class bsn_get_interfaces_reply(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 10
+
+    def __init__(self, xid=None, interfaces=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if interfaces != None:
+            self.interfaces = interfaces
+        else:
+            self.interfaces = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.interfaces))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_get_interfaces_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 10)
+        obj.interfaces = loxi.generic_util.unpack_list(reader, ofp.common.bsn_interface.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.interfaces != other.interfaces: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_get_interfaces_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("interfaces = ");
+                q.pp(self.interfaces)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[10] = bsn_get_interfaces_reply
+
+class bsn_get_interfaces_request(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 9
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_get_interfaces_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 9)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_get_interfaces_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[9] = bsn_get_interfaces_request
+
+class bsn_get_mirroring_reply(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 5
+
+    def __init__(self, xid=None, report_mirror_ports=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if report_mirror_ports != None:
+            self.report_mirror_ports = report_mirror_ports
+        else:
+            self.report_mirror_ports = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!B", self.report_mirror_ports))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_get_mirroring_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 5)
+        obj.report_mirror_ports = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.report_mirror_ports != other.report_mirror_ports: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_get_mirroring_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("report_mirror_ports = ");
+                q.text("%#x" % self.report_mirror_ports)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[5] = bsn_get_mirroring_reply
+
+class bsn_get_mirroring_request(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 4
+
+    def __init__(self, xid=None, report_mirror_ports=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if report_mirror_ports != None:
+            self.report_mirror_ports = report_mirror_ports
+        else:
+            self.report_mirror_ports = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!B", self.report_mirror_ports))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_get_mirroring_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 4)
+        obj.report_mirror_ports = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.report_mirror_ports != other.report_mirror_ports: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_get_mirroring_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("report_mirror_ports = ");
+                q.text("%#x" % self.report_mirror_ports)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[4] = bsn_get_mirroring_request
+
+class bsn_get_switch_pipeline_reply(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 52
+
+    def __init__(self, xid=None, pipeline=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if pipeline != None:
+            self.pipeline = pipeline
+        else:
+            self.pipeline = ""
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!256s", self.pipeline))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_get_switch_pipeline_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 52)
+        obj.pipeline = reader.read("!256s")[0].rstrip("\x00")
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.pipeline != other.pipeline: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_get_switch_pipeline_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("pipeline = ");
+                q.pp(self.pipeline)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[52] = bsn_get_switch_pipeline_reply
+
+class bsn_get_switch_pipeline_request(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 51
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_get_switch_pipeline_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 51)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_get_switch_pipeline_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[51] = bsn_get_switch_pipeline_request
+
+class bsn_image_desc_stats_reply(bsn_stats_reply):
+    version = 4
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 14
+
+    def __init__(self, xid=None, flags=None, image_checksum=None, startup_config_checksum=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if image_checksum != None:
+            self.image_checksum = image_checksum
+        else:
+            self.image_checksum = ""
+        if startup_config_checksum != None:
+            self.startup_config_checksum = startup_config_checksum
+        else:
+            self.startup_config_checksum = ""
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!256s", self.image_checksum))
+        packed.append(struct.pack("!256s", self.startup_config_checksum))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_image_desc_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 14)
+        obj.image_checksum = reader.read("!256s")[0].rstrip("\x00")
+        obj.startup_config_checksum = reader.read("!256s")[0].rstrip("\x00")
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.image_checksum != other.image_checksum: return False
+        if self.startup_config_checksum != other.startup_config_checksum: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_image_desc_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("image_checksum = ");
+                q.pp(self.image_checksum)
+                q.text(","); q.breakable()
+                q.text("startup_config_checksum = ");
+                q.pp(self.startup_config_checksum)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_reply.subtypes[14] = bsn_image_desc_stats_reply
+
+class bsn_image_desc_stats_request(bsn_stats_request):
+    version = 4
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 14
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_image_desc_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 14)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_image_desc_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_request.subtypes[14] = bsn_image_desc_stats_request
+
+class bsn_lacp_convergence_notif(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 43
+
+    def __init__(self, xid=None, convergence_status=None, port_no=None, actor_sys_priority=None, actor_sys_mac=None, actor_port_priority=None, actor_port_num=None, actor_key=None, partner_sys_priority=None, partner_sys_mac=None, partner_port_priority=None, partner_port_num=None, partner_key=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if convergence_status != None:
+            self.convergence_status = convergence_status
+        else:
+            self.convergence_status = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if actor_sys_priority != None:
+            self.actor_sys_priority = actor_sys_priority
+        else:
+            self.actor_sys_priority = 0
+        if actor_sys_mac != None:
+            self.actor_sys_mac = actor_sys_mac
+        else:
+            self.actor_sys_mac = [0,0,0,0,0,0]
+        if actor_port_priority != None:
+            self.actor_port_priority = actor_port_priority
+        else:
+            self.actor_port_priority = 0
+        if actor_port_num != None:
+            self.actor_port_num = actor_port_num
+        else:
+            self.actor_port_num = 0
+        if actor_key != None:
+            self.actor_key = actor_key
+        else:
+            self.actor_key = 0
+        if partner_sys_priority != None:
+            self.partner_sys_priority = partner_sys_priority
+        else:
+            self.partner_sys_priority = 0
+        if partner_sys_mac != None:
+            self.partner_sys_mac = partner_sys_mac
+        else:
+            self.partner_sys_mac = [0,0,0,0,0,0]
+        if partner_port_priority != None:
+            self.partner_port_priority = partner_port_priority
+        else:
+            self.partner_port_priority = 0
+        if partner_port_num != None:
+            self.partner_port_num = partner_port_num
+        else:
+            self.partner_port_num = 0
+        if partner_key != None:
+            self.partner_key = partner_key
+        else:
+            self.partner_key = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!B", self.convergence_status))
+        packed.append('\x00' * 3)
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!H", self.actor_sys_priority))
+        packed.append(struct.pack("!6B", *self.actor_sys_mac))
+        packed.append(struct.pack("!H", self.actor_port_priority))
+        packed.append(struct.pack("!H", self.actor_port_num))
+        packed.append(struct.pack("!H", self.actor_key))
+        packed.append(struct.pack("!H", self.partner_sys_priority))
+        packed.append(struct.pack("!6B", *self.partner_sys_mac))
+        packed.append(struct.pack("!H", self.partner_port_priority))
+        packed.append(struct.pack("!H", self.partner_port_num))
+        packed.append(struct.pack("!H", self.partner_key))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_lacp_convergence_notif()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 43)
+        obj.convergence_status = reader.read("!B")[0]
+        reader.skip(3)
+        obj.port_no = util.unpack_port_no(reader)
+        obj.actor_sys_priority = reader.read("!H")[0]
+        obj.actor_sys_mac = list(reader.read('!6B'))
+        obj.actor_port_priority = reader.read("!H")[0]
+        obj.actor_port_num = reader.read("!H")[0]
+        obj.actor_key = reader.read("!H")[0]
+        obj.partner_sys_priority = reader.read("!H")[0]
+        obj.partner_sys_mac = list(reader.read('!6B'))
+        obj.partner_port_priority = reader.read("!H")[0]
+        obj.partner_port_num = reader.read("!H")[0]
+        obj.partner_key = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.convergence_status != other.convergence_status: return False
+        if self.port_no != other.port_no: return False
+        if self.actor_sys_priority != other.actor_sys_priority: return False
+        if self.actor_sys_mac != other.actor_sys_mac: return False
+        if self.actor_port_priority != other.actor_port_priority: return False
+        if self.actor_port_num != other.actor_port_num: return False
+        if self.actor_key != other.actor_key: return False
+        if self.partner_sys_priority != other.partner_sys_priority: return False
+        if self.partner_sys_mac != other.partner_sys_mac: return False
+        if self.partner_port_priority != other.partner_port_priority: return False
+        if self.partner_port_num != other.partner_port_num: return False
+        if self.partner_key != other.partner_key: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_lacp_convergence_notif {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("convergence_status = ");
+                q.text("%#x" % self.convergence_status)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("actor_sys_priority = ");
+                q.text("%#x" % self.actor_sys_priority)
+                q.text(","); q.breakable()
+                q.text("actor_sys_mac = ");
+                q.text(util.pretty_mac(self.actor_sys_mac))
+                q.text(","); q.breakable()
+                q.text("actor_port_priority = ");
+                q.text("%#x" % self.actor_port_priority)
+                q.text(","); q.breakable()
+                q.text("actor_port_num = ");
+                q.text("%#x" % self.actor_port_num)
+                q.text(","); q.breakable()
+                q.text("actor_key = ");
+                q.text("%#x" % self.actor_key)
+                q.text(","); q.breakable()
+                q.text("partner_sys_priority = ");
+                q.text("%#x" % self.partner_sys_priority)
+                q.text(","); q.breakable()
+                q.text("partner_sys_mac = ");
+                q.text(util.pretty_mac(self.partner_sys_mac))
+                q.text(","); q.breakable()
+                q.text("partner_port_priority = ");
+                q.text("%#x" % self.partner_port_priority)
+                q.text(","); q.breakable()
+                q.text("partner_port_num = ");
+                q.text("%#x" % self.partner_port_num)
+                q.text(","); q.breakable()
+                q.text("partner_key = ");
+                q.text("%#x" % self.partner_key)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[43] = bsn_lacp_convergence_notif
+
+class bsn_lacp_stats_reply(bsn_stats_reply):
+    version = 4
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 1
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_lacp_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 1)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.bsn_lacp_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_lacp_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_reply.subtypes[1] = bsn_lacp_stats_reply
+
+class bsn_lacp_stats_request(bsn_stats_request):
+    version = 4
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 1
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_lacp_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 1)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_lacp_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_request.subtypes[1] = bsn_lacp_stats_request
+
+class bsn_log(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 63
+
+    def __init__(self, xid=None, loglevel=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if loglevel != None:
+            self.loglevel = loglevel
+        else:
+            self.loglevel = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!B", self.loglevel))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_log()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 63)
+        obj.loglevel = reader.read("!B")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.loglevel != other.loglevel: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_log {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("loglevel = ");
+                q.text("%#x" % self.loglevel)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[63] = bsn_log
+
+class bsn_lua_command_reply(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 66
+
+    def __init__(self, xid=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_lua_command_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 66)
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_lua_command_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[66] = bsn_lua_command_reply
+
+class bsn_lua_command_request(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 65
+
+    def __init__(self, xid=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_lua_command_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 65)
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_lua_command_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[65] = bsn_lua_command_request
+
+class bsn_lua_notification(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 67
+
+    def __init__(self, xid=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_lua_notification()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 67)
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_lua_notification {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[67] = bsn_lua_notification
+
+class bsn_lua_upload(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 64
+
+    def __init__(self, xid=None, flags=None, filename=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if filename != None:
+            self.filename = filename
+        else:
+            self.filename = ""
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(struct.pack("!64s", self.filename))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_lua_upload()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 64)
+        obj.flags = reader.read("!H")[0]
+        obj.filename = reader.read("!64s")[0].rstrip("\x00")
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.filename != other.filename: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_lua_upload {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("filename = ");
+                q.pp(self.filename)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[64] = bsn_lua_upload
+
+class bsn_pdu_rx_reply(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 34
+
+    def __init__(self, xid=None, status=None, port_no=None, slot_num=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if slot_num != None:
+            self.slot_num = slot_num
+        else:
+            self.slot_num = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.status))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!B", self.slot_num))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_pdu_rx_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 34)
+        obj.status = reader.read("!L")[0]
+        obj.port_no = util.unpack_port_no(reader)
+        obj.slot_num = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.status != other.status: return False
+        if self.port_no != other.port_no: return False
+        if self.slot_num != other.slot_num: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_pdu_rx_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("slot_num = ");
+                q.text("%#x" % self.slot_num)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[34] = bsn_pdu_rx_reply
+
+class bsn_pdu_rx_request(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 33
+
+    def __init__(self, xid=None, timeout_ms=None, port_no=None, slot_num=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if timeout_ms != None:
+            self.timeout_ms = timeout_ms
+        else:
+            self.timeout_ms = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if slot_num != None:
+            self.slot_num = slot_num
+        else:
+            self.slot_num = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.timeout_ms))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!B", self.slot_num))
+        packed.append('\x00' * 3)
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_pdu_rx_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 33)
+        obj.timeout_ms = reader.read("!L")[0]
+        obj.port_no = util.unpack_port_no(reader)
+        obj.slot_num = reader.read("!B")[0]
+        reader.skip(3)
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.timeout_ms != other.timeout_ms: return False
+        if self.port_no != other.port_no: return False
+        if self.slot_num != other.slot_num: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_pdu_rx_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("timeout_ms = ");
+                q.text("%#x" % self.timeout_ms)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("slot_num = ");
+                q.text("%#x" % self.slot_num)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[33] = bsn_pdu_rx_request
+
+class bsn_pdu_rx_timeout(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 35
+
+    def __init__(self, xid=None, port_no=None, slot_num=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if slot_num != None:
+            self.slot_num = slot_num
+        else:
+            self.slot_num = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!B", self.slot_num))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_pdu_rx_timeout()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 35)
+        obj.port_no = util.unpack_port_no(reader)
+        obj.slot_num = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.port_no != other.port_no: return False
+        if self.slot_num != other.slot_num: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_pdu_rx_timeout {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("slot_num = ");
+                q.text("%#x" % self.slot_num)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[35] = bsn_pdu_rx_timeout
+
+class bsn_pdu_tx_reply(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 32
+
+    def __init__(self, xid=None, status=None, port_no=None, slot_num=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if slot_num != None:
+            self.slot_num = slot_num
+        else:
+            self.slot_num = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.status))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!B", self.slot_num))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_pdu_tx_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 32)
+        obj.status = reader.read("!L")[0]
+        obj.port_no = util.unpack_port_no(reader)
+        obj.slot_num = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.status != other.status: return False
+        if self.port_no != other.port_no: return False
+        if self.slot_num != other.slot_num: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_pdu_tx_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("slot_num = ");
+                q.text("%#x" % self.slot_num)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[32] = bsn_pdu_tx_reply
+
+class bsn_pdu_tx_request(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 31
+
+    def __init__(self, xid=None, tx_interval_ms=None, port_no=None, slot_num=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if tx_interval_ms != None:
+            self.tx_interval_ms = tx_interval_ms
+        else:
+            self.tx_interval_ms = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if slot_num != None:
+            self.slot_num = slot_num
+        else:
+            self.slot_num = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.tx_interval_ms))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!B", self.slot_num))
+        packed.append('\x00' * 3)
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_pdu_tx_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 31)
+        obj.tx_interval_ms = reader.read("!L")[0]
+        obj.port_no = util.unpack_port_no(reader)
+        obj.slot_num = reader.read("!B")[0]
+        reader.skip(3)
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.tx_interval_ms != other.tx_interval_ms: return False
+        if self.port_no != other.port_no: return False
+        if self.slot_num != other.slot_num: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_pdu_tx_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("tx_interval_ms = ");
+                q.text("%#x" % self.tx_interval_ms)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("slot_num = ");
+                q.text("%#x" % self.slot_num)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[31] = bsn_pdu_tx_request
+
+class bsn_port_counter_stats_reply(bsn_stats_reply):
+    version = 4
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 8
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_port_counter_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 8)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.bsn_port_counter_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_port_counter_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_reply.subtypes[8] = bsn_port_counter_stats_reply
+
+class bsn_port_counter_stats_request(bsn_stats_request):
+    version = 4
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 8
+
+    def __init__(self, xid=None, flags=None, port_no=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(util.pack_port_no(self.port_no))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_port_counter_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 8)
+        obj.port_no = util.unpack_port_no(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.port_no != other.port_no: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_port_counter_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+            q.breakable()
+        q.text('}')
+
+bsn_stats_request.subtypes[8] = bsn_port_counter_stats_request
+
+class bsn_role_status(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 55
+
+    def __init__(self, xid=None, role=None, reason=None, generation_id=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if role != None:
+            self.role = role
+        else:
+            self.role = 0
+        if reason != None:
+            self.reason = reason
+        else:
+            self.reason = 0
+        if generation_id != None:
+            self.generation_id = generation_id
+        else:
+            self.generation_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.role))
+        packed.append(struct.pack("!B", self.reason))
+        packed.append('\x00' * 3)
+        packed.append(struct.pack("!Q", self.generation_id))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_role_status()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 55)
+        obj.role = reader.read("!L")[0]
+        obj.reason = reader.read("!B")[0]
+        reader.skip(3)
+        obj.generation_id = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.role != other.role: return False
+        if self.reason != other.reason: return False
+        if self.generation_id != other.generation_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_role_status {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("role = ");
+                q.text("%#x" % self.role)
+                q.text(","); q.breakable()
+                q.text("reason = ");
+                q.text("%#x" % self.reason)
+                q.text(","); q.breakable()
+                q.text("generation_id = ");
+                q.text("%#x" % self.generation_id)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[55] = bsn_role_status
+
+class bsn_set_aux_cxns_reply(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 59
+
+    def __init__(self, xid=None, num_aux=None, status=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if num_aux != None:
+            self.num_aux = num_aux
+        else:
+            self.num_aux = 0
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.num_aux))
+        packed.append(struct.pack("!L", self.status))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_aux_cxns_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 59)
+        obj.num_aux = reader.read("!L")[0]
+        obj.status = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.num_aux != other.num_aux: return False
+        if self.status != other.status: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_aux_cxns_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("num_aux = ");
+                q.text("%#x" % self.num_aux)
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[59] = bsn_set_aux_cxns_reply
+
+class bsn_set_aux_cxns_request(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 58
+
+    def __init__(self, xid=None, num_aux=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if num_aux != None:
+            self.num_aux = num_aux
+        else:
+            self.num_aux = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.num_aux))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_aux_cxns_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 58)
+        obj.num_aux = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.num_aux != other.num_aux: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_aux_cxns_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("num_aux = ");
+                q.text("%#x" % self.num_aux)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[58] = bsn_set_aux_cxns_request
+
+class bsn_set_lacp_reply(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 42
+
+    def __init__(self, xid=None, status=None, port_no=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.status))
+        packed.append(util.pack_port_no(self.port_no))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_lacp_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 42)
+        obj.status = reader.read("!L")[0]
+        obj.port_no = util.unpack_port_no(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.status != other.status: return False
+        if self.port_no != other.port_no: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_lacp_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[42] = bsn_set_lacp_reply
+
+class bsn_set_lacp_request(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 41
+
+    def __init__(self, xid=None, enabled=None, port_no=None, actor_sys_priority=None, actor_sys_mac=None, actor_port_priority=None, actor_port_num=None, actor_key=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if enabled != None:
+            self.enabled = enabled
+        else:
+            self.enabled = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if actor_sys_priority != None:
+            self.actor_sys_priority = actor_sys_priority
+        else:
+            self.actor_sys_priority = 0
+        if actor_sys_mac != None:
+            self.actor_sys_mac = actor_sys_mac
+        else:
+            self.actor_sys_mac = [0,0,0,0,0,0]
+        if actor_port_priority != None:
+            self.actor_port_priority = actor_port_priority
+        else:
+            self.actor_port_priority = 0
+        if actor_port_num != None:
+            self.actor_port_num = actor_port_num
+        else:
+            self.actor_port_num = 0
+        if actor_key != None:
+            self.actor_key = actor_key
+        else:
+            self.actor_key = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!B", self.enabled))
+        packed.append('\x00' * 3)
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!H", self.actor_sys_priority))
+        packed.append(struct.pack("!6B", *self.actor_sys_mac))
+        packed.append(struct.pack("!H", self.actor_port_priority))
+        packed.append(struct.pack("!H", self.actor_port_num))
+        packed.append(struct.pack("!H", self.actor_key))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_lacp_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 41)
+        obj.enabled = reader.read("!B")[0]
+        reader.skip(3)
+        obj.port_no = util.unpack_port_no(reader)
+        obj.actor_sys_priority = reader.read("!H")[0]
+        obj.actor_sys_mac = list(reader.read('!6B'))
+        obj.actor_port_priority = reader.read("!H")[0]
+        obj.actor_port_num = reader.read("!H")[0]
+        obj.actor_key = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.enabled != other.enabled: return False
+        if self.port_no != other.port_no: return False
+        if self.actor_sys_priority != other.actor_sys_priority: return False
+        if self.actor_sys_mac != other.actor_sys_mac: return False
+        if self.actor_port_priority != other.actor_port_priority: return False
+        if self.actor_port_num != other.actor_port_num: return False
+        if self.actor_key != other.actor_key: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_lacp_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("enabled = ");
+                q.text("%#x" % self.enabled)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("actor_sys_priority = ");
+                q.text("%#x" % self.actor_sys_priority)
+                q.text(","); q.breakable()
+                q.text("actor_sys_mac = ");
+                q.text(util.pretty_mac(self.actor_sys_mac))
+                q.text(","); q.breakable()
+                q.text("actor_port_priority = ");
+                q.text("%#x" % self.actor_port_priority)
+                q.text(","); q.breakable()
+                q.text("actor_port_num = ");
+                q.text("%#x" % self.actor_port_num)
+                q.text(","); q.breakable()
+                q.text("actor_key = ");
+                q.text("%#x" % self.actor_key)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[41] = bsn_set_lacp_request
+
+class bsn_set_mirroring(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 3
+
+    def __init__(self, xid=None, report_mirror_ports=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if report_mirror_ports != None:
+            self.report_mirror_ports = report_mirror_ports
+        else:
+            self.report_mirror_ports = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!B", self.report_mirror_ports))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_mirroring()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 3)
+        obj.report_mirror_ports = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.report_mirror_ports != other.report_mirror_ports: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_mirroring {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("report_mirror_ports = ");
+                q.text("%#x" % self.report_mirror_ports)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[3] = bsn_set_mirroring
+
+class bsn_set_pktin_suppression_reply(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 25
+
+    def __init__(self, xid=None, status=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.status))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_pktin_suppression_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 25)
+        obj.status = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.status != other.status: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_pktin_suppression_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[25] = bsn_set_pktin_suppression_reply
+
+class bsn_set_pktin_suppression_request(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 11
+
+    def __init__(self, xid=None, enabled=None, idle_timeout=None, hard_timeout=None, priority=None, cookie=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if enabled != None:
+            self.enabled = enabled
+        else:
+            self.enabled = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!B", self.enabled))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!Q", self.cookie))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_pktin_suppression_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 11)
+        obj.enabled = reader.read("!B")[0]
+        reader.skip(1)
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.cookie = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.enabled != other.enabled: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.priority != other.priority: return False
+        if self.cookie != other.cookie: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_pktin_suppression_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("enabled = ");
+                q.text("%#x" % self.enabled)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[11] = bsn_set_pktin_suppression_request
+
+class bsn_set_switch_pipeline_reply(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 54
+
+    def __init__(self, xid=None, status=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.status))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_switch_pipeline_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 54)
+        obj.status = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.status != other.status: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_switch_pipeline_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[54] = bsn_set_switch_pipeline_reply
+
+class bsn_set_switch_pipeline_request(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 53
+
+    def __init__(self, xid=None, pipeline=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if pipeline != None:
+            self.pipeline = pipeline
+        else:
+            self.pipeline = ""
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!256s", self.pipeline))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_switch_pipeline_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 53)
+        obj.pipeline = reader.read("!256s")[0].rstrip("\x00")
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.pipeline != other.pipeline: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_switch_pipeline_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("pipeline = ");
+                q.pp(self.pipeline)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[53] = bsn_set_switch_pipeline_request
+
+class bsn_switch_pipeline_stats_reply(bsn_stats_reply):
+    version = 4
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 6
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_switch_pipeline_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 6)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.bsn_switch_pipeline_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_switch_pipeline_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_reply.subtypes[6] = bsn_switch_pipeline_stats_reply
+
+class bsn_switch_pipeline_stats_request(bsn_stats_request):
+    version = 4
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 6
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_switch_pipeline_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 6)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_switch_pipeline_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_request.subtypes[6] = bsn_switch_pipeline_stats_request
+
+class bsn_table_checksum_stats_reply(bsn_stats_reply):
+    version = 4
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 11
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_table_checksum_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 11)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.bsn_table_checksum_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_table_checksum_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_reply.subtypes[11] = bsn_table_checksum_stats_reply
+
+class bsn_table_checksum_stats_request(bsn_stats_request):
+    version = 4
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 11
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_table_checksum_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 11)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_table_checksum_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_request.subtypes[11] = bsn_table_checksum_stats_request
+
+class bsn_table_set_buckets_size(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 61
+
+    def __init__(self, xid=None, table_id=None, buckets_size=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if buckets_size != None:
+            self.buckets_size = buckets_size
+        else:
+            self.buckets_size = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!L", self.buckets_size))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_table_set_buckets_size()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 61)
+        reader.skip(1)
+        obj.table_id = reader.read("!B")[0]
+        reader.skip(2)
+        obj.buckets_size = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.table_id != other.table_id: return False
+        if self.buckets_size != other.buckets_size: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_table_set_buckets_size {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("buckets_size = ");
+                q.text("%#x" % self.buckets_size)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[61] = bsn_table_set_buckets_size
+
+class bsn_time_reply(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 45
+
+    def __init__(self, xid=None, time_ms=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if time_ms != None:
+            self.time_ms = time_ms
+        else:
+            self.time_ms = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!Q", self.time_ms))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_time_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 45)
+        obj.time_ms = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.time_ms != other.time_ms: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_time_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("time_ms = ");
+                q.text("%#x" % self.time_ms)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[45] = bsn_time_reply
+
+class bsn_time_request(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 44
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_time_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 44)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_time_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[44] = bsn_time_request
+
+class bsn_virtual_port_create_reply(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 16
+
+    def __init__(self, xid=None, status=None, vport_no=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        if vport_no != None:
+            self.vport_no = vport_no
+        else:
+            self.vport_no = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.status))
+        packed.append(struct.pack("!L", self.vport_no))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_virtual_port_create_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 16)
+        obj.status = reader.read("!L")[0]
+        obj.vport_no = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.status != other.status: return False
+        if self.vport_no != other.vport_no: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_virtual_port_create_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+                q.text(","); q.breakable()
+                q.text("vport_no = ");
+                q.text("%#x" % self.vport_no)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[16] = bsn_virtual_port_create_reply
+
+class bsn_virtual_port_create_request(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 15
+
+    def __init__(self, xid=None, vport=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if vport != None:
+            self.vport = vport
+        else:
+            self.vport = ofp.bsn_vport()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(self.vport.pack())
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_virtual_port_create_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 15)
+        obj.vport = ofp.bsn_vport.unpack(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.vport != other.vport: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_virtual_port_create_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("vport = ");
+                q.pp(self.vport)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[15] = bsn_virtual_port_create_request
+
+class bsn_virtual_port_remove_reply(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 26
+
+    def __init__(self, xid=None, status=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.status))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_virtual_port_remove_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 26)
+        obj.status = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.status != other.status: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_virtual_port_remove_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[26] = bsn_virtual_port_remove_reply
+
+class bsn_virtual_port_remove_request(bsn_header):
+    version = 4
+    type = 4
+    experimenter = 6035143
+    subtype = 17
+
+    def __init__(self, xid=None, vport_no=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if vport_no != None:
+            self.vport_no = vport_no
+        else:
+            self.vport_no = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.vport_no))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_virtual_port_remove_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 17)
+        obj.vport_no = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.vport_no != other.vport_no: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_virtual_port_remove_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("vport_no = ");
+                q.text("%#x" % self.vport_no)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[17] = bsn_virtual_port_remove_request
+
+class bsn_vlan_counter_stats_reply(bsn_stats_reply):
+    version = 4
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 9
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vlan_counter_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 9)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.bsn_vlan_counter_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vlan_counter_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_reply.subtypes[9] = bsn_vlan_counter_stats_reply
+
+class bsn_vlan_counter_stats_request(bsn_stats_request):
+    version = 4
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 9
+
+    def __init__(self, xid=None, flags=None, vlan_vid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if vlan_vid != None:
+            self.vlan_vid = vlan_vid
+        else:
+            self.vlan_vid = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!H", self.vlan_vid))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vlan_counter_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 9)
+        obj.vlan_vid = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.vlan_vid != other.vlan_vid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vlan_counter_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("vlan_vid = ");
+                q.text("%#x" % self.vlan_vid)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_request.subtypes[9] = bsn_vlan_counter_stats_request
+
+class bsn_vrf_counter_stats_reply(bsn_stats_reply):
+    version = 4
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 15
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vrf_counter_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 15)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.bsn_vrf_counter_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vrf_counter_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_reply.subtypes[15] = bsn_vrf_counter_stats_reply
+
+class bsn_vrf_counter_stats_request(bsn_stats_request):
+    version = 4
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 15
+
+    def __init__(self, xid=None, flags=None, vrf=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if vrf != None:
+            self.vrf = vrf
+        else:
+            self.vrf = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.vrf))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vrf_counter_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 15)
+        obj.vrf = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.vrf != other.vrf: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vrf_counter_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("vrf = ");
+                q.text("%#x" % self.vrf)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_request.subtypes[15] = bsn_vrf_counter_stats_request
+
+class desc_stats_reply(stats_reply):
+    version = 4
+    type = 19
+    stats_type = 0
+
+    def __init__(self, xid=None, flags=None, mfr_desc=None, hw_desc=None, sw_desc=None, serial_num=None, dp_desc=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if mfr_desc != None:
+            self.mfr_desc = mfr_desc
+        else:
+            self.mfr_desc = ""
+        if hw_desc != None:
+            self.hw_desc = hw_desc
+        else:
+            self.hw_desc = ""
+        if sw_desc != None:
+            self.sw_desc = sw_desc
+        else:
+            self.sw_desc = ""
+        if serial_num != None:
+            self.serial_num = serial_num
+        else:
+            self.serial_num = ""
+        if dp_desc != None:
+            self.dp_desc = dp_desc
+        else:
+            self.dp_desc = ""
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!256s", self.mfr_desc))
+        packed.append(struct.pack("!256s", self.hw_desc))
+        packed.append(struct.pack("!256s", self.sw_desc))
+        packed.append(struct.pack("!32s", self.serial_num))
+        packed.append(struct.pack("!256s", self.dp_desc))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = desc_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 0)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.mfr_desc = reader.read("!256s")[0].rstrip("\x00")
+        obj.hw_desc = reader.read("!256s")[0].rstrip("\x00")
+        obj.sw_desc = reader.read("!256s")[0].rstrip("\x00")
+        obj.serial_num = reader.read("!32s")[0].rstrip("\x00")
+        obj.dp_desc = reader.read("!256s")[0].rstrip("\x00")
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.mfr_desc != other.mfr_desc: return False
+        if self.hw_desc != other.hw_desc: return False
+        if self.sw_desc != other.sw_desc: return False
+        if self.serial_num != other.serial_num: return False
+        if self.dp_desc != other.dp_desc: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("desc_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("mfr_desc = ");
+                q.pp(self.mfr_desc)
+                q.text(","); q.breakable()
+                q.text("hw_desc = ");
+                q.pp(self.hw_desc)
+                q.text(","); q.breakable()
+                q.text("sw_desc = ");
+                q.pp(self.sw_desc)
+                q.text(","); q.breakable()
+                q.text("serial_num = ");
+                q.pp(self.serial_num)
+                q.text(","); q.breakable()
+                q.text("dp_desc = ");
+                q.pp(self.dp_desc)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[0] = desc_stats_reply
+
+class desc_stats_request(stats_request):
+    version = 4
+    type = 18
+    stats_type = 0
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = desc_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 0)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("desc_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[0] = desc_stats_request
+
+class echo_reply(message):
+    version = 4
+    type = 3
+
+    def __init__(self, xid=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = echo_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 3)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("echo_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[3] = echo_reply
+
+class echo_request(message):
+    version = 4
+    type = 2
+
+    def __init__(self, xid=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = echo_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 2)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("echo_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[2] = echo_request
+
+class experimenter_error_msg(error_msg):
+    version = 4
+    type = 1
+    err_type = 65535
+
+    def __init__(self, xid=None, subtype=None, experimenter=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.subtype))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = experimenter_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 65535)
+        obj.subtype = reader.read("!H")[0]
+        obj.experimenter = reader.read("!L")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.subtype != other.subtype: return False
+        if self.experimenter != other.experimenter: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("subtype = ");
+                q.text("%#x" % self.subtype)
+                q.text(","); q.breakable()
+                q.text("experimenter = ");
+                q.text("%#x" % self.experimenter)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[65535] = experimenter_error_msg
+
+class features_reply(message):
+    version = 4
+    type = 6
+
+    def __init__(self, xid=None, datapath_id=None, n_buffers=None, n_tables=None, auxiliary_id=None, capabilities=None, reserved=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if datapath_id != None:
+            self.datapath_id = datapath_id
+        else:
+            self.datapath_id = 0
+        if n_buffers != None:
+            self.n_buffers = n_buffers
+        else:
+            self.n_buffers = 0
+        if n_tables != None:
+            self.n_tables = n_tables
+        else:
+            self.n_tables = 0
+        if auxiliary_id != None:
+            self.auxiliary_id = auxiliary_id
+        else:
+            self.auxiliary_id = 0
+        if capabilities != None:
+            self.capabilities = capabilities
+        else:
+            self.capabilities = 0
+        if reserved != None:
+            self.reserved = reserved
+        else:
+            self.reserved = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!Q", self.datapath_id))
+        packed.append(struct.pack("!L", self.n_buffers))
+        packed.append(struct.pack("!B", self.n_tables))
+        packed.append(struct.pack("!B", self.auxiliary_id))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!L", self.capabilities))
+        packed.append(struct.pack("!L", self.reserved))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = features_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 6)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.datapath_id = reader.read("!Q")[0]
+        obj.n_buffers = reader.read("!L")[0]
+        obj.n_tables = reader.read("!B")[0]
+        obj.auxiliary_id = reader.read("!B")[0]
+        reader.skip(2)
+        obj.capabilities = reader.read("!L")[0]
+        obj.reserved = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.datapath_id != other.datapath_id: return False
+        if self.n_buffers != other.n_buffers: return False
+        if self.n_tables != other.n_tables: return False
+        if self.auxiliary_id != other.auxiliary_id: return False
+        if self.capabilities != other.capabilities: return False
+        if self.reserved != other.reserved: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("features_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("datapath_id = ");
+                q.text("%#x" % self.datapath_id)
+                q.text(","); q.breakable()
+                q.text("n_buffers = ");
+                q.text("%#x" % self.n_buffers)
+                q.text(","); q.breakable()
+                q.text("n_tables = ");
+                q.text("%#x" % self.n_tables)
+                q.text(","); q.breakable()
+                q.text("auxiliary_id = ");
+                q.text("%#x" % self.auxiliary_id)
+                q.text(","); q.breakable()
+                q.text("capabilities = ");
+                q.text("%#x" % self.capabilities)
+                q.text(","); q.breakable()
+                q.text("reserved = ");
+                q.text("%#x" % self.reserved)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[6] = features_reply
+
+class features_request(message):
+    version = 4
+    type = 5
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = features_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 5)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("features_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+message.subtypes[5] = features_request
+
+class flow_mod(message):
+    subtypes = {}
+
+    version = 4
+    type = 14
+
+    def __init__(self, xid=None, cookie=None, cookie_mask=None, table_id=None, _command=None, idle_timeout=None, hard_timeout=None, priority=None, buffer_id=None, out_port=None, out_group=None, flags=None, match=None, instructions=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if cookie_mask != None:
+            self.cookie_mask = cookie_mask
+        else:
+            self.cookie_mask = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if _command != None:
+            self._command = _command
+        else:
+            self._command = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if out_group != None:
+            self.out_group = out_group
+        else:
+            self.out_group = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if instructions != None:
+            self.instructions = instructions
+        else:
+            self.instructions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.cookie_mask))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append(util.pack_fm_cmd(self._command))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!L", self.out_group))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 2)
+        packed.append(self.match.pack())
+        packed.append(loxi.generic_util.pack_list(self.instructions))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('B', 25)
+        subclass = flow_mod.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = flow_mod()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 14)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.cookie = reader.read("!Q")[0]
+        obj.cookie_mask = reader.read("!Q")[0]
+        obj.table_id = reader.read("!B")[0]
+        obj._command = util.unpack_fm_cmd(reader)
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.out_port = util.unpack_port_no(reader)
+        obj.out_group = reader.read("!L")[0]
+        obj.flags = reader.read("!H")[0]
+        reader.skip(2)
+        obj.match = ofp.match.unpack(reader)
+        obj.instructions = loxi.generic_util.unpack_list(reader, ofp.instruction.instruction.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.cookie != other.cookie: return False
+        if self.cookie_mask != other.cookie_mask: return False
+        if self.table_id != other.table_id: return False
+        if self._command != other._command: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.priority != other.priority: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.out_port != other.out_port: return False
+        if self.out_group != other.out_group: return False
+        if self.flags != other.flags: return False
+        if self.match != other.match: return False
+        if self.instructions != other.instructions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_mod {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("cookie_mask = ");
+                q.text("%#x" % self.cookie_mask)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("out_group = ");
+                q.text("%#x" % self.out_group)
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("instructions = ");
+                q.pp(self.instructions)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[14] = flow_mod
+
+class flow_add(flow_mod):
+    version = 4
+    type = 14
+    _command = 0
+
+    def __init__(self, xid=None, cookie=None, cookie_mask=None, table_id=None, idle_timeout=None, hard_timeout=None, priority=None, buffer_id=None, out_port=None, out_group=None, flags=None, match=None, instructions=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if cookie_mask != None:
+            self.cookie_mask = cookie_mask
+        else:
+            self.cookie_mask = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if out_group != None:
+            self.out_group = out_group
+        else:
+            self.out_group = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if instructions != None:
+            self.instructions = instructions
+        else:
+            self.instructions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.cookie_mask))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append(util.pack_fm_cmd(self._command))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!L", self.out_group))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 2)
+        packed.append(self.match.pack())
+        packed.append(loxi.generic_util.pack_list(self.instructions))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_add()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 14)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.cookie = reader.read("!Q")[0]
+        obj.cookie_mask = reader.read("!Q")[0]
+        obj.table_id = reader.read("!B")[0]
+        __command = util.unpack_fm_cmd(reader)
+        assert(__command == 0)
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.out_port = util.unpack_port_no(reader)
+        obj.out_group = reader.read("!L")[0]
+        obj.flags = reader.read("!H")[0]
+        reader.skip(2)
+        obj.match = ofp.match.unpack(reader)
+        obj.instructions = loxi.generic_util.unpack_list(reader, ofp.instruction.instruction.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.cookie != other.cookie: return False
+        if self.cookie_mask != other.cookie_mask: return False
+        if self.table_id != other.table_id: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.priority != other.priority: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.out_port != other.out_port: return False
+        if self.out_group != other.out_group: return False
+        if self.flags != other.flags: return False
+        if self.match != other.match: return False
+        if self.instructions != other.instructions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_add {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("cookie_mask = ");
+                q.text("%#x" % self.cookie_mask)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("out_group = ");
+                q.text("%#x" % self.out_group)
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("instructions = ");
+                q.pp(self.instructions)
+            q.breakable()
+        q.text('}')
+
+flow_mod.subtypes[0] = flow_add
+
+class flow_delete(flow_mod):
+    version = 4
+    type = 14
+    _command = 3
+
+    def __init__(self, xid=None, cookie=None, cookie_mask=None, table_id=None, idle_timeout=None, hard_timeout=None, priority=None, buffer_id=None, out_port=None, out_group=None, flags=None, match=None, instructions=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if cookie_mask != None:
+            self.cookie_mask = cookie_mask
+        else:
+            self.cookie_mask = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if out_group != None:
+            self.out_group = out_group
+        else:
+            self.out_group = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if instructions != None:
+            self.instructions = instructions
+        else:
+            self.instructions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.cookie_mask))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append(util.pack_fm_cmd(self._command))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!L", self.out_group))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 2)
+        packed.append(self.match.pack())
+        packed.append(loxi.generic_util.pack_list(self.instructions))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_delete()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 14)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.cookie = reader.read("!Q")[0]
+        obj.cookie_mask = reader.read("!Q")[0]
+        obj.table_id = reader.read("!B")[0]
+        __command = util.unpack_fm_cmd(reader)
+        assert(__command == 3)
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.out_port = util.unpack_port_no(reader)
+        obj.out_group = reader.read("!L")[0]
+        obj.flags = reader.read("!H")[0]
+        reader.skip(2)
+        obj.match = ofp.match.unpack(reader)
+        obj.instructions = loxi.generic_util.unpack_list(reader, ofp.instruction.instruction.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.cookie != other.cookie: return False
+        if self.cookie_mask != other.cookie_mask: return False
+        if self.table_id != other.table_id: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.priority != other.priority: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.out_port != other.out_port: return False
+        if self.out_group != other.out_group: return False
+        if self.flags != other.flags: return False
+        if self.match != other.match: return False
+        if self.instructions != other.instructions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_delete {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("cookie_mask = ");
+                q.text("%#x" % self.cookie_mask)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("out_group = ");
+                q.text("%#x" % self.out_group)
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("instructions = ");
+                q.pp(self.instructions)
+            q.breakable()
+        q.text('}')
+
+flow_mod.subtypes[3] = flow_delete
+
+class flow_delete_strict(flow_mod):
+    version = 4
+    type = 14
+    _command = 4
+
+    def __init__(self, xid=None, cookie=None, cookie_mask=None, table_id=None, idle_timeout=None, hard_timeout=None, priority=None, buffer_id=None, out_port=None, out_group=None, flags=None, match=None, instructions=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if cookie_mask != None:
+            self.cookie_mask = cookie_mask
+        else:
+            self.cookie_mask = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if out_group != None:
+            self.out_group = out_group
+        else:
+            self.out_group = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if instructions != None:
+            self.instructions = instructions
+        else:
+            self.instructions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.cookie_mask))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append(util.pack_fm_cmd(self._command))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!L", self.out_group))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 2)
+        packed.append(self.match.pack())
+        packed.append(loxi.generic_util.pack_list(self.instructions))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_delete_strict()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 14)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.cookie = reader.read("!Q")[0]
+        obj.cookie_mask = reader.read("!Q")[0]
+        obj.table_id = reader.read("!B")[0]
+        __command = util.unpack_fm_cmd(reader)
+        assert(__command == 4)
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.out_port = util.unpack_port_no(reader)
+        obj.out_group = reader.read("!L")[0]
+        obj.flags = reader.read("!H")[0]
+        reader.skip(2)
+        obj.match = ofp.match.unpack(reader)
+        obj.instructions = loxi.generic_util.unpack_list(reader, ofp.instruction.instruction.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.cookie != other.cookie: return False
+        if self.cookie_mask != other.cookie_mask: return False
+        if self.table_id != other.table_id: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.priority != other.priority: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.out_port != other.out_port: return False
+        if self.out_group != other.out_group: return False
+        if self.flags != other.flags: return False
+        if self.match != other.match: return False
+        if self.instructions != other.instructions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_delete_strict {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("cookie_mask = ");
+                q.text("%#x" % self.cookie_mask)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("out_group = ");
+                q.text("%#x" % self.out_group)
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("instructions = ");
+                q.pp(self.instructions)
+            q.breakable()
+        q.text('}')
+
+flow_mod.subtypes[4] = flow_delete_strict
+
+class flow_mod_failed_error_msg(error_msg):
+    version = 4
+    type = 1
+    err_type = 5
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_mod_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 5)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_mod_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[5] = flow_mod_failed_error_msg
+
+class flow_modify(flow_mod):
+    version = 4
+    type = 14
+    _command = 1
+
+    def __init__(self, xid=None, cookie=None, cookie_mask=None, table_id=None, idle_timeout=None, hard_timeout=None, priority=None, buffer_id=None, out_port=None, out_group=None, flags=None, match=None, instructions=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if cookie_mask != None:
+            self.cookie_mask = cookie_mask
+        else:
+            self.cookie_mask = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if out_group != None:
+            self.out_group = out_group
+        else:
+            self.out_group = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if instructions != None:
+            self.instructions = instructions
+        else:
+            self.instructions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.cookie_mask))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append(util.pack_fm_cmd(self._command))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!L", self.out_group))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 2)
+        packed.append(self.match.pack())
+        packed.append(loxi.generic_util.pack_list(self.instructions))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_modify()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 14)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.cookie = reader.read("!Q")[0]
+        obj.cookie_mask = reader.read("!Q")[0]
+        obj.table_id = reader.read("!B")[0]
+        __command = util.unpack_fm_cmd(reader)
+        assert(__command == 1)
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.out_port = util.unpack_port_no(reader)
+        obj.out_group = reader.read("!L")[0]
+        obj.flags = reader.read("!H")[0]
+        reader.skip(2)
+        obj.match = ofp.match.unpack(reader)
+        obj.instructions = loxi.generic_util.unpack_list(reader, ofp.instruction.instruction.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.cookie != other.cookie: return False
+        if self.cookie_mask != other.cookie_mask: return False
+        if self.table_id != other.table_id: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.priority != other.priority: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.out_port != other.out_port: return False
+        if self.out_group != other.out_group: return False
+        if self.flags != other.flags: return False
+        if self.match != other.match: return False
+        if self.instructions != other.instructions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_modify {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("cookie_mask = ");
+                q.text("%#x" % self.cookie_mask)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("out_group = ");
+                q.text("%#x" % self.out_group)
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("instructions = ");
+                q.pp(self.instructions)
+            q.breakable()
+        q.text('}')
+
+flow_mod.subtypes[1] = flow_modify
+
+class flow_modify_strict(flow_mod):
+    version = 4
+    type = 14
+    _command = 2
+
+    def __init__(self, xid=None, cookie=None, cookie_mask=None, table_id=None, idle_timeout=None, hard_timeout=None, priority=None, buffer_id=None, out_port=None, out_group=None, flags=None, match=None, instructions=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if cookie_mask != None:
+            self.cookie_mask = cookie_mask
+        else:
+            self.cookie_mask = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if out_group != None:
+            self.out_group = out_group
+        else:
+            self.out_group = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if instructions != None:
+            self.instructions = instructions
+        else:
+            self.instructions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.cookie_mask))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append(util.pack_fm_cmd(self._command))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!L", self.out_group))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 2)
+        packed.append(self.match.pack())
+        packed.append(loxi.generic_util.pack_list(self.instructions))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_modify_strict()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 14)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.cookie = reader.read("!Q")[0]
+        obj.cookie_mask = reader.read("!Q")[0]
+        obj.table_id = reader.read("!B")[0]
+        __command = util.unpack_fm_cmd(reader)
+        assert(__command == 2)
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.out_port = util.unpack_port_no(reader)
+        obj.out_group = reader.read("!L")[0]
+        obj.flags = reader.read("!H")[0]
+        reader.skip(2)
+        obj.match = ofp.match.unpack(reader)
+        obj.instructions = loxi.generic_util.unpack_list(reader, ofp.instruction.instruction.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.cookie != other.cookie: return False
+        if self.cookie_mask != other.cookie_mask: return False
+        if self.table_id != other.table_id: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.priority != other.priority: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.out_port != other.out_port: return False
+        if self.out_group != other.out_group: return False
+        if self.flags != other.flags: return False
+        if self.match != other.match: return False
+        if self.instructions != other.instructions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_modify_strict {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("cookie_mask = ");
+                q.text("%#x" % self.cookie_mask)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("out_group = ");
+                q.text("%#x" % self.out_group)
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("instructions = ");
+                q.pp(self.instructions)
+            q.breakable()
+        q.text('}')
+
+flow_mod.subtypes[2] = flow_modify_strict
+
+class flow_removed(message):
+    version = 4
+    type = 11
+
+    def __init__(self, xid=None, cookie=None, priority=None, reason=None, table_id=None, duration_sec=None, duration_nsec=None, idle_timeout=None, hard_timeout=None, packet_count=None, byte_count=None, match=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if reason != None:
+            self.reason = reason
+        else:
+            self.reason = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if duration_sec != None:
+            self.duration_sec = duration_sec
+        else:
+            self.duration_sec = 0
+        if duration_nsec != None:
+            self.duration_nsec = duration_nsec
+        else:
+            self.duration_nsec = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if packet_count != None:
+            self.packet_count = packet_count
+        else:
+            self.packet_count = 0
+        if byte_count != None:
+            self.byte_count = byte_count
+        else:
+            self.byte_count = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!B", self.reason))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append(struct.pack("!L", self.duration_sec))
+        packed.append(struct.pack("!L", self.duration_nsec))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!Q", self.packet_count))
+        packed.append(struct.pack("!Q", self.byte_count))
+        packed.append(self.match.pack())
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_removed()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 11)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.cookie = reader.read("!Q")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.reason = reader.read("!B")[0]
+        obj.table_id = reader.read("!B")[0]
+        obj.duration_sec = reader.read("!L")[0]
+        obj.duration_nsec = reader.read("!L")[0]
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.packet_count = reader.read("!Q")[0]
+        obj.byte_count = reader.read("!Q")[0]
+        obj.match = ofp.match.unpack(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.cookie != other.cookie: return False
+        if self.priority != other.priority: return False
+        if self.reason != other.reason: return False
+        if self.table_id != other.table_id: return False
+        if self.duration_sec != other.duration_sec: return False
+        if self.duration_nsec != other.duration_nsec: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.packet_count != other.packet_count: return False
+        if self.byte_count != other.byte_count: return False
+        if self.match != other.match: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_removed {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("reason = ");
+                q.text("%#x" % self.reason)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("duration_sec = ");
+                q.text("%#x" % self.duration_sec)
+                q.text(","); q.breakable()
+                q.text("duration_nsec = ");
+                q.text("%#x" % self.duration_nsec)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("packet_count = ");
+                q.text("%#x" % self.packet_count)
+                q.text(","); q.breakable()
+                q.text("byte_count = ");
+                q.text("%#x" % self.byte_count)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[11] = flow_removed
+
+class flow_stats_reply(stats_reply):
+    version = 4
+    type = 19
+    stats_type = 1
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 1)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.flow_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[1] = flow_stats_reply
+
+class flow_stats_request(stats_request):
+    version = 4
+    type = 18
+    stats_type = 1
+
+    def __init__(self, xid=None, flags=None, table_id=None, out_port=None, out_group=None, cookie=None, cookie_mask=None, match=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if out_group != None:
+            self.out_group = out_group
+        else:
+            self.out_group = 0
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if cookie_mask != None:
+            self.cookie_mask = cookie_mask
+        else:
+            self.cookie_mask = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append('\x00' * 3)
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!L", self.out_group))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.cookie_mask))
+        packed.append(self.match.pack())
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 1)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.table_id = reader.read("!B")[0]
+        reader.skip(3)
+        obj.out_port = util.unpack_port_no(reader)
+        obj.out_group = reader.read("!L")[0]
+        reader.skip(4)
+        obj.cookie = reader.read("!Q")[0]
+        obj.cookie_mask = reader.read("!Q")[0]
+        obj.match = ofp.match.unpack(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.table_id != other.table_id: return False
+        if self.out_port != other.out_port: return False
+        if self.out_group != other.out_group: return False
+        if self.cookie != other.cookie: return False
+        if self.cookie_mask != other.cookie_mask: return False
+        if self.match != other.match: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("out_group = ");
+                q.text("%#x" % self.out_group)
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("cookie_mask = ");
+                q.text("%#x" % self.cookie_mask)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[1] = flow_stats_request
+
+class get_config_reply(message):
+    version = 4
+    type = 8
+
+    def __init__(self, xid=None, flags=None, miss_send_len=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if miss_send_len != None:
+            self.miss_send_len = miss_send_len
+        else:
+            self.miss_send_len = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(struct.pack("!H", self.miss_send_len))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = get_config_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 8)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.flags = reader.read("!H")[0]
+        obj.miss_send_len = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.miss_send_len != other.miss_send_len: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("get_config_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("miss_send_len = ");
+                q.text("%#x" % self.miss_send_len)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[8] = get_config_reply
+
+class get_config_request(message):
+    version = 4
+    type = 7
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = get_config_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 7)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("get_config_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+message.subtypes[7] = get_config_request
+
+class group_mod(message):
+    subtypes = {}
+
+    version = 4
+    type = 15
+
+    def __init__(self, xid=None, command=None, group_type=None, group_id=None, buckets=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if command != None:
+            self.command = command
+        else:
+            self.command = 0
+        if group_type != None:
+            self.group_type = group_type
+        else:
+            self.group_type = 0
+        if group_id != None:
+            self.group_id = group_id
+        else:
+            self.group_id = 0
+        if buckets != None:
+            self.buckets = buckets
+        else:
+            self.buckets = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.command))
+        packed.append(struct.pack("!B", self.group_type))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!L", self.group_id))
+        packed.append(loxi.generic_util.pack_list(self.buckets))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 8)
+        subclass = group_mod.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = group_mod()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 15)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.command = reader.read("!H")[0]
+        obj.group_type = reader.read("!B")[0]
+        reader.skip(1)
+        obj.group_id = reader.read("!L")[0]
+        obj.buckets = loxi.generic_util.unpack_list(reader, ofp.common.bucket.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.command != other.command: return False
+        if self.group_type != other.group_type: return False
+        if self.group_id != other.group_id: return False
+        if self.buckets != other.buckets: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_mod {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("group_type = ");
+                q.text("%#x" % self.group_type)
+                q.text(","); q.breakable()
+                q.text("group_id = ");
+                q.text("%#x" % self.group_id)
+                q.text(","); q.breakable()
+                q.text("buckets = ");
+                q.pp(self.buckets)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[15] = group_mod
+
+class group_add(group_mod):
+    version = 4
+    type = 15
+    command = 0
+
+    def __init__(self, xid=None, group_type=None, group_id=None, buckets=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if group_type != None:
+            self.group_type = group_type
+        else:
+            self.group_type = 0
+        if group_id != None:
+            self.group_id = group_id
+        else:
+            self.group_id = 0
+        if buckets != None:
+            self.buckets = buckets
+        else:
+            self.buckets = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.command))
+        packed.append(struct.pack("!B", self.group_type))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!L", self.group_id))
+        packed.append(loxi.generic_util.pack_list(self.buckets))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_add()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 15)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _command = reader.read("!H")[0]
+        assert(_command == 0)
+        obj.group_type = reader.read("!B")[0]
+        reader.skip(1)
+        obj.group_id = reader.read("!L")[0]
+        obj.buckets = loxi.generic_util.unpack_list(reader, ofp.common.bucket.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.group_type != other.group_type: return False
+        if self.group_id != other.group_id: return False
+        if self.buckets != other.buckets: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_add {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("group_type = ");
+                q.text("%#x" % self.group_type)
+                q.text(","); q.breakable()
+                q.text("group_id = ");
+                q.text("%#x" % self.group_id)
+                q.text(","); q.breakable()
+                q.text("buckets = ");
+                q.pp(self.buckets)
+            q.breakable()
+        q.text('}')
+
+group_mod.subtypes[0] = group_add
+
+class group_delete(group_mod):
+    version = 4
+    type = 15
+    command = 2
+
+    def __init__(self, xid=None, group_type=None, group_id=None, buckets=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if group_type != None:
+            self.group_type = group_type
+        else:
+            self.group_type = 0
+        if group_id != None:
+            self.group_id = group_id
+        else:
+            self.group_id = 0
+        if buckets != None:
+            self.buckets = buckets
+        else:
+            self.buckets = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.command))
+        packed.append(struct.pack("!B", self.group_type))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!L", self.group_id))
+        packed.append(loxi.generic_util.pack_list(self.buckets))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_delete()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 15)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _command = reader.read("!H")[0]
+        assert(_command == 2)
+        obj.group_type = reader.read("!B")[0]
+        reader.skip(1)
+        obj.group_id = reader.read("!L")[0]
+        obj.buckets = loxi.generic_util.unpack_list(reader, ofp.common.bucket.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.group_type != other.group_type: return False
+        if self.group_id != other.group_id: return False
+        if self.buckets != other.buckets: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_delete {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("group_type = ");
+                q.text("%#x" % self.group_type)
+                q.text(","); q.breakable()
+                q.text("group_id = ");
+                q.text("%#x" % self.group_id)
+                q.text(","); q.breakable()
+                q.text("buckets = ");
+                q.pp(self.buckets)
+            q.breakable()
+        q.text('}')
+
+group_mod.subtypes[2] = group_delete
+
+class group_desc_stats_reply(stats_reply):
+    version = 4
+    type = 19
+    stats_type = 7
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_desc_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 7)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.group_desc_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_desc_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[7] = group_desc_stats_reply
+
+class group_desc_stats_request(stats_request):
+    version = 4
+    type = 18
+    stats_type = 7
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_desc_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 7)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_desc_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[7] = group_desc_stats_request
+
+class group_features_stats_reply(stats_reply):
+    version = 4
+    type = 19
+    stats_type = 8
+
+    def __init__(self, xid=None, flags=None, types=None, capabilities=None, max_groups_all=None, max_groups_select=None, max_groups_indirect=None, max_groups_ff=None, actions_all=None, actions_select=None, actions_indirect=None, actions_ff=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if types != None:
+            self.types = types
+        else:
+            self.types = 0
+        if capabilities != None:
+            self.capabilities = capabilities
+        else:
+            self.capabilities = 0
+        if max_groups_all != None:
+            self.max_groups_all = max_groups_all
+        else:
+            self.max_groups_all = 0
+        if max_groups_select != None:
+            self.max_groups_select = max_groups_select
+        else:
+            self.max_groups_select = 0
+        if max_groups_indirect != None:
+            self.max_groups_indirect = max_groups_indirect
+        else:
+            self.max_groups_indirect = 0
+        if max_groups_ff != None:
+            self.max_groups_ff = max_groups_ff
+        else:
+            self.max_groups_ff = 0
+        if actions_all != None:
+            self.actions_all = actions_all
+        else:
+            self.actions_all = 0
+        if actions_select != None:
+            self.actions_select = actions_select
+        else:
+            self.actions_select = 0
+        if actions_indirect != None:
+            self.actions_indirect = actions_indirect
+        else:
+            self.actions_indirect = 0
+        if actions_ff != None:
+            self.actions_ff = actions_ff
+        else:
+            self.actions_ff = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.types))
+        packed.append(struct.pack("!L", self.capabilities))
+        packed.append(struct.pack("!L", self.max_groups_all))
+        packed.append(struct.pack("!L", self.max_groups_select))
+        packed.append(struct.pack("!L", self.max_groups_indirect))
+        packed.append(struct.pack("!L", self.max_groups_ff))
+        packed.append(struct.pack("!L", self.actions_all))
+        packed.append(struct.pack("!L", self.actions_select))
+        packed.append(struct.pack("!L", self.actions_indirect))
+        packed.append(struct.pack("!L", self.actions_ff))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_features_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 8)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.types = reader.read("!L")[0]
+        obj.capabilities = reader.read("!L")[0]
+        obj.max_groups_all = reader.read("!L")[0]
+        obj.max_groups_select = reader.read("!L")[0]
+        obj.max_groups_indirect = reader.read("!L")[0]
+        obj.max_groups_ff = reader.read("!L")[0]
+        obj.actions_all = reader.read("!L")[0]
+        obj.actions_select = reader.read("!L")[0]
+        obj.actions_indirect = reader.read("!L")[0]
+        obj.actions_ff = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.types != other.types: return False
+        if self.capabilities != other.capabilities: return False
+        if self.max_groups_all != other.max_groups_all: return False
+        if self.max_groups_select != other.max_groups_select: return False
+        if self.max_groups_indirect != other.max_groups_indirect: return False
+        if self.max_groups_ff != other.max_groups_ff: return False
+        if self.actions_all != other.actions_all: return False
+        if self.actions_select != other.actions_select: return False
+        if self.actions_indirect != other.actions_indirect: return False
+        if self.actions_ff != other.actions_ff: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_features_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("types = ");
+                q.text("%#x" % self.types)
+                q.text(","); q.breakable()
+                q.text("capabilities = ");
+                q.text("%#x" % self.capabilities)
+                q.text(","); q.breakable()
+                q.text("max_groups_all = ");
+                q.text("%#x" % self.max_groups_all)
+                q.text(","); q.breakable()
+                q.text("max_groups_select = ");
+                q.text("%#x" % self.max_groups_select)
+                q.text(","); q.breakable()
+                q.text("max_groups_indirect = ");
+                q.text("%#x" % self.max_groups_indirect)
+                q.text(","); q.breakable()
+                q.text("max_groups_ff = ");
+                q.text("%#x" % self.max_groups_ff)
+                q.text(","); q.breakable()
+                q.text("actions_all = ");
+                q.text("%#x" % self.actions_all)
+                q.text(","); q.breakable()
+                q.text("actions_select = ");
+                q.text("%#x" % self.actions_select)
+                q.text(","); q.breakable()
+                q.text("actions_indirect = ");
+                q.text("%#x" % self.actions_indirect)
+                q.text(","); q.breakable()
+                q.text("actions_ff = ");
+                q.text("%#x" % self.actions_ff)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[8] = group_features_stats_reply
+
+class group_features_stats_request(stats_request):
+    version = 4
+    type = 18
+    stats_type = 8
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_features_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 8)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_features_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[8] = group_features_stats_request
+
+class group_mod_failed_error_msg(error_msg):
+    version = 4
+    type = 1
+    err_type = 6
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_mod_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 6)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_mod_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[6] = group_mod_failed_error_msg
+
+class group_modify(group_mod):
+    version = 4
+    type = 15
+    command = 1
+
+    def __init__(self, xid=None, group_type=None, group_id=None, buckets=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if group_type != None:
+            self.group_type = group_type
+        else:
+            self.group_type = 0
+        if group_id != None:
+            self.group_id = group_id
+        else:
+            self.group_id = 0
+        if buckets != None:
+            self.buckets = buckets
+        else:
+            self.buckets = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.command))
+        packed.append(struct.pack("!B", self.group_type))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!L", self.group_id))
+        packed.append(loxi.generic_util.pack_list(self.buckets))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_modify()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 15)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _command = reader.read("!H")[0]
+        assert(_command == 1)
+        obj.group_type = reader.read("!B")[0]
+        reader.skip(1)
+        obj.group_id = reader.read("!L")[0]
+        obj.buckets = loxi.generic_util.unpack_list(reader, ofp.common.bucket.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.group_type != other.group_type: return False
+        if self.group_id != other.group_id: return False
+        if self.buckets != other.buckets: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_modify {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("group_type = ");
+                q.text("%#x" % self.group_type)
+                q.text(","); q.breakable()
+                q.text("group_id = ");
+                q.text("%#x" % self.group_id)
+                q.text(","); q.breakable()
+                q.text("buckets = ");
+                q.pp(self.buckets)
+            q.breakable()
+        q.text('}')
+
+group_mod.subtypes[1] = group_modify
+
+class group_stats_reply(stats_reply):
+    version = 4
+    type = 19
+    stats_type = 6
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 6)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.group_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[6] = group_stats_reply
+
+class group_stats_request(stats_request):
+    version = 4
+    type = 18
+    stats_type = 6
+
+    def __init__(self, xid=None, flags=None, group_id=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if group_id != None:
+            self.group_id = group_id
+        else:
+            self.group_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.group_id))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 6)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.group_id = reader.read("!L")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.group_id != other.group_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("group_id = ");
+                q.text("%#x" % self.group_id)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[6] = group_stats_request
+
+class hello(message):
+    version = 4
+    type = 0
+
+    def __init__(self, xid=None, elements=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if elements != None:
+            self.elements = elements
+        else:
+            self.elements = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(loxi.generic_util.pack_list(self.elements))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = hello()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 0)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.elements = loxi.generic_util.unpack_list(reader, ofp.common.hello_elem.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.elements != other.elements: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("hello {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("elements = ");
+                q.pp(self.elements)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[0] = hello
+
+class hello_failed_error_msg(error_msg):
+    version = 4
+    type = 1
+    err_type = 0
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = hello_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 0)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("hello_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[0] = hello_failed_error_msg
+
+class meter_config_stats_reply(stats_reply):
+    version = 4
+    type = 19
+    stats_type = 10
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = meter_config_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 10)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.meter_band.meter_band.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("meter_config_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[10] = meter_config_stats_reply
+
+class meter_config_stats_request(stats_request):
+    version = 4
+    type = 18
+    stats_type = 10
+
+    def __init__(self, xid=None, flags=None, meter_id=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if meter_id != None:
+            self.meter_id = meter_id
+        else:
+            self.meter_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.meter_id))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = meter_config_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 10)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.meter_id = reader.read("!L")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.meter_id != other.meter_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("meter_config_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("meter_id = ");
+                q.text("%#x" % self.meter_id)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[10] = meter_config_stats_request
+
+class meter_features_stats_reply(stats_reply):
+    version = 4
+    type = 19
+    stats_type = 11
+
+    def __init__(self, xid=None, flags=None, features=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if features != None:
+            self.features = features
+        else:
+            self.features = ofp.meter_features()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(self.features.pack())
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = meter_features_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 11)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.features = ofp.meter_features.unpack(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.features != other.features: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("meter_features_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("features = ");
+                q.pp(self.features)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[11] = meter_features_stats_reply
+
+class meter_features_stats_request(stats_request):
+    version = 4
+    type = 18
+    stats_type = 11
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = meter_features_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 11)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("meter_features_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[11] = meter_features_stats_request
+
+class meter_mod(message):
+    version = 4
+    type = 29
+
+    def __init__(self, xid=None, command=None, flags=None, meter_id=None, meters=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if command != None:
+            self.command = command
+        else:
+            self.command = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if meter_id != None:
+            self.meter_id = meter_id
+        else:
+            self.meter_id = 0
+        if meters != None:
+            self.meters = meters
+        else:
+            self.meters = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.command))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(struct.pack("!L", self.meter_id))
+        packed.append(loxi.generic_util.pack_list(self.meters))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = meter_mod()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 29)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.command = reader.read("!H")[0]
+        obj.flags = reader.read("!H")[0]
+        obj.meter_id = reader.read("!L")[0]
+        obj.meters = loxi.generic_util.unpack_list(reader, ofp.meter_band.meter_band.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.command != other.command: return False
+        if self.flags != other.flags: return False
+        if self.meter_id != other.meter_id: return False
+        if self.meters != other.meters: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("meter_mod {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("command = ");
+                q.text("%#x" % self.command)
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("meter_id = ");
+                q.text("%#x" % self.meter_id)
+                q.text(","); q.breakable()
+                q.text("meters = ");
+                q.pp(self.meters)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[29] = meter_mod
+
+class meter_mod_failed_error_msg(error_msg):
+    version = 4
+    type = 1
+    err_type = 12
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = meter_mod_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 12)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("meter_mod_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[12] = meter_mod_failed_error_msg
+
+class meter_stats_reply(stats_reply):
+    version = 4
+    type = 19
+    stats_type = 9
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = meter_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 9)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.meter_stats.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("meter_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[9] = meter_stats_reply
+
+class meter_stats_request(stats_request):
+    version = 4
+    type = 18
+    stats_type = 9
+
+    def __init__(self, xid=None, flags=None, meter_id=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if meter_id != None:
+            self.meter_id = meter_id
+        else:
+            self.meter_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.meter_id))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = meter_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 9)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.meter_id = reader.read("!L")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.meter_id != other.meter_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("meter_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("meter_id = ");
+                q.text("%#x" % self.meter_id)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[9] = meter_stats_request
+
+class nicira_header(experimenter):
+    subtypes = {}
+
+    version = 4
+    type = 4
+    experimenter = 8992
+
+    def __init__(self, xid=None, subtype=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 12)
+        subclass = nicira_header.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = nicira_header()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 8992)
+        obj.subtype = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("nicira_header {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+experimenter.subtypes[8992] = nicira_header
+
+class packet_in(message):
+    version = 4
+    type = 10
+
+    def __init__(self, xid=None, buffer_id=None, total_len=None, reason=None, table_id=None, cookie=None, match=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if total_len != None:
+            self.total_len = total_len
+        else:
+            self.total_len = 0
+        if reason != None:
+            self.reason = reason
+        else:
+            self.reason = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(struct.pack("!H", self.total_len))
+        packed.append(struct.pack("!B", self.reason))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(self.match.pack())
+        packed.append('\x00' * 2)
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = packet_in()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 10)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.total_len = reader.read("!H")[0]
+        obj.reason = reader.read("!B")[0]
+        obj.table_id = reader.read("!B")[0]
+        obj.cookie = reader.read("!Q")[0]
+        obj.match = ofp.match.unpack(reader)
+        reader.skip(2)
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.total_len != other.total_len: return False
+        if self.reason != other.reason: return False
+        if self.table_id != other.table_id: return False
+        if self.cookie != other.cookie: return False
+        if self.match != other.match: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("packet_in {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("total_len = ");
+                q.text("%#x" % self.total_len)
+                q.text(","); q.breakable()
+                q.text("reason = ");
+                q.text("%#x" % self.reason)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[10] = packet_in
+
+class packet_out(message):
+    version = 4
+    type = 13
+
+    def __init__(self, xid=None, buffer_id=None, in_port=None, actions=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if in_port != None:
+            self.in_port = in_port
+        else:
+            self.in_port = 0
+        if actions != None:
+            self.actions = actions
+        else:
+            self.actions = []
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(util.pack_port_no(self.in_port))
+        packed.append(struct.pack("!H", 0)) # placeholder for actions_len at index 6
+        packed.append('\x00' * 6)
+        packed.append(loxi.generic_util.pack_list(self.actions))
+        packed[6] = struct.pack("!H", len(packed[-1]))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = packet_out()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 13)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.in_port = util.unpack_port_no(reader)
+        _actions_len = reader.read("!H")[0]
+        reader.skip(6)
+        obj.actions = loxi.generic_util.unpack_list(reader.slice(_actions_len), ofp.action.action.unpack)
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.in_port != other.in_port: return False
+        if self.actions != other.actions: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("packet_out {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("in_port = ");
+                q.text(util.pretty_port(self.in_port))
+                q.text(","); q.breakable()
+                q.text("actions = ");
+                q.pp(self.actions)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[13] = packet_out
+
+class port_desc_stats_reply(stats_reply):
+    version = 4
+    type = 19
+    stats_type = 13
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_desc_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 13)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.port_desc.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_desc_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[13] = port_desc_stats_reply
+
+class port_desc_stats_request(stats_request):
+    version = 4
+    type = 18
+    stats_type = 13
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_desc_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 13)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_desc_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[13] = port_desc_stats_request
+
+class port_mod(message):
+    version = 4
+    type = 16
+
+    def __init__(self, xid=None, port_no=None, hw_addr=None, config=None, mask=None, advertise=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if hw_addr != None:
+            self.hw_addr = hw_addr
+        else:
+            self.hw_addr = [0,0,0,0,0,0]
+        if config != None:
+            self.config = config
+        else:
+            self.config = 0
+        if mask != None:
+            self.mask = mask
+        else:
+            self.mask = 0
+        if advertise != None:
+            self.advertise = advertise
+        else:
+            self.advertise = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!6B", *self.hw_addr))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!L", self.config))
+        packed.append(struct.pack("!L", self.mask))
+        packed.append(struct.pack("!L", self.advertise))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_mod()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 16)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.port_no = util.unpack_port_no(reader)
+        reader.skip(4)
+        obj.hw_addr = list(reader.read('!6B'))
+        reader.skip(2)
+        obj.config = reader.read("!L")[0]
+        obj.mask = reader.read("!L")[0]
+        obj.advertise = reader.read("!L")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.port_no != other.port_no: return False
+        if self.hw_addr != other.hw_addr: return False
+        if self.config != other.config: return False
+        if self.mask != other.mask: return False
+        if self.advertise != other.advertise: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_mod {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("hw_addr = ");
+                q.text(util.pretty_mac(self.hw_addr))
+                q.text(","); q.breakable()
+                q.text("config = ");
+                q.text("%#x" % self.config)
+                q.text(","); q.breakable()
+                q.text("mask = ");
+                q.text("%#x" % self.mask)
+                q.text(","); q.breakable()
+                q.text("advertise = ");
+                q.text("%#x" % self.advertise)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[16] = port_mod
+
+class port_mod_failed_error_msg(error_msg):
+    version = 4
+    type = 1
+    err_type = 7
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_mod_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 7)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_mod_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[7] = port_mod_failed_error_msg
+
+class port_stats_reply(stats_reply):
+    version = 4
+    type = 19
+    stats_type = 4
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 4)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.port_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[4] = port_stats_reply
+
+class port_stats_request(stats_request):
+    version = 4
+    type = 18
+    stats_type = 4
+
+    def __init__(self, xid=None, flags=None, port_no=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 4)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.port_no = util.unpack_port_no(reader)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.port_no != other.port_no: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[4] = port_stats_request
+
+class port_status(message):
+    version = 4
+    type = 12
+
+    def __init__(self, xid=None, reason=None, desc=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if reason != None:
+            self.reason = reason
+        else:
+            self.reason = 0
+        if desc != None:
+            self.desc = desc
+        else:
+            self.desc = ofp.port_desc()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!B", self.reason))
+        packed.append('\x00' * 7)
+        packed.append(self.desc.pack())
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_status()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 12)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.reason = reader.read("!B")[0]
+        reader.skip(7)
+        obj.desc = ofp.port_desc.unpack(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.reason != other.reason: return False
+        if self.desc != other.desc: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_status {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("reason = ");
+                q.text("%#x" % self.reason)
+                q.text(","); q.breakable()
+                q.text("desc = ");
+                q.pp(self.desc)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[12] = port_status
+
+class queue_get_config_reply(message):
+    version = 4
+    type = 23
+
+    def __init__(self, xid=None, port=None, queues=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if port != None:
+            self.port = port
+        else:
+            self.port = 0
+        if queues != None:
+            self.queues = queues
+        else:
+            self.queues = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(util.pack_port_no(self.port))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.queues))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_get_config_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 23)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.port = util.unpack_port_no(reader)
+        reader.skip(4)
+        obj.queues = loxi.generic_util.unpack_list(reader, ofp.common.packet_queue.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.port != other.port: return False
+        if self.queues != other.queues: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_get_config_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("port = ");
+                q.text(util.pretty_port(self.port))
+                q.text(","); q.breakable()
+                q.text("queues = ");
+                q.pp(self.queues)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[23] = queue_get_config_reply
+
+class queue_get_config_request(message):
+    version = 4
+    type = 22
+
+    def __init__(self, xid=None, port=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if port != None:
+            self.port = port
+        else:
+            self.port = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(util.pack_port_no(self.port))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_get_config_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 22)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.port = util.unpack_port_no(reader)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.port != other.port: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_get_config_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("port = ");
+                q.text(util.pretty_port(self.port))
+            q.breakable()
+        q.text('}')
+
+message.subtypes[22] = queue_get_config_request
+
+class queue_op_failed_error_msg(error_msg):
+    version = 4
+    type = 1
+    err_type = 9
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_op_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 9)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_op_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[9] = queue_op_failed_error_msg
+
+class queue_stats_reply(stats_reply):
+    version = 4
+    type = 19
+    stats_type = 5
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 5)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.queue_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[5] = queue_stats_reply
+
+class queue_stats_request(stats_request):
+    version = 4
+    type = 18
+    stats_type = 5
+
+    def __init__(self, xid=None, flags=None, port_no=None, queue_id=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if queue_id != None:
+            self.queue_id = queue_id
+        else:
+            self.queue_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!L", self.queue_id))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 5)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.port_no = util.unpack_port_no(reader)
+        obj.queue_id = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.port_no != other.port_no: return False
+        if self.queue_id != other.queue_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("queue_id = ");
+                q.text("%#x" % self.queue_id)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[5] = queue_stats_request
+
+class role_reply(message):
+    version = 4
+    type = 25
+
+    def __init__(self, xid=None, role=None, generation_id=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if role != None:
+            self.role = role
+        else:
+            self.role = 0
+        if generation_id != None:
+            self.generation_id = generation_id
+        else:
+            self.generation_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.role))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!Q", self.generation_id))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = role_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 25)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.role = reader.read("!L")[0]
+        reader.skip(4)
+        obj.generation_id = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.role != other.role: return False
+        if self.generation_id != other.generation_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("role_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("role = ");
+                q.text("%#x" % self.role)
+                q.text(","); q.breakable()
+                q.text("generation_id = ");
+                q.text("%#x" % self.generation_id)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[25] = role_reply
+
+class role_request(message):
+    version = 4
+    type = 24
+
+    def __init__(self, xid=None, role=None, generation_id=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if role != None:
+            self.role = role
+        else:
+            self.role = 0
+        if generation_id != None:
+            self.generation_id = generation_id
+        else:
+            self.generation_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.role))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!Q", self.generation_id))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = role_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 24)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.role = reader.read("!L")[0]
+        reader.skip(4)
+        obj.generation_id = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.role != other.role: return False
+        if self.generation_id != other.generation_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("role_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("role = ");
+                q.text("%#x" % self.role)
+                q.text(","); q.breakable()
+                q.text("generation_id = ");
+                q.text("%#x" % self.generation_id)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[24] = role_request
+
+class role_request_failed_error_msg(error_msg):
+    version = 4
+    type = 1
+    err_type = 11
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = role_request_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 11)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("role_request_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[11] = role_request_failed_error_msg
+
+class set_config(message):
+    version = 4
+    type = 9
+
+    def __init__(self, xid=None, flags=None, miss_send_len=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if miss_send_len != None:
+            self.miss_send_len = miss_send_len
+        else:
+            self.miss_send_len = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(struct.pack("!H", self.miss_send_len))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_config()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 9)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.flags = reader.read("!H")[0]
+        obj.miss_send_len = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.miss_send_len != other.miss_send_len: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_config {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("miss_send_len = ");
+                q.text("%#x" % self.miss_send_len)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[9] = set_config
+
+class switch_config_failed_error_msg(error_msg):
+    version = 4
+    type = 1
+    err_type = 10
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = switch_config_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 10)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("switch_config_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[10] = switch_config_failed_error_msg
+
+class table_features_failed_error_msg(error_msg):
+    version = 4
+    type = 1
+    err_type = 13
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_features_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 13)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_features_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[13] = table_features_failed_error_msg
+
+class table_features_stats_reply(stats_reply):
+    version = 4
+    type = 19
+    stats_type = 12
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_features_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 12)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.table_features.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_features_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[12] = table_features_stats_reply
+
+class table_features_stats_request(stats_request):
+    version = 4
+    type = 18
+    stats_type = 12
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_features_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 12)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.table_features.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_features_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[12] = table_features_stats_request
+
+class table_mod(message):
+    version = 4
+    type = 17
+
+    def __init__(self, xid=None, table_id=None, config=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if config != None:
+            self.config = config
+        else:
+            self.config = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append('\x00' * 3)
+        packed.append(struct.pack("!L", self.config))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_mod()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 17)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.table_id = reader.read("!B")[0]
+        reader.skip(3)
+        obj.config = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.table_id != other.table_id: return False
+        if self.config != other.config: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_mod {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("config = ");
+                q.text("%#x" % self.config)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[17] = table_mod
+
+class table_mod_failed_error_msg(error_msg):
+    version = 4
+    type = 1
+    err_type = 8
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_mod_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 8)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_mod_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[8] = table_mod_failed_error_msg
+
+class table_stats_reply(stats_reply):
+    version = 4
+    type = 19
+    stats_type = 3
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 3)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.table_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[3] = table_stats_reply
+
+class table_stats_request(stats_request):
+    version = 4
+    type = 18
+    stats_type = 3
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 4)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 3)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[3] = table_stats_request
+
+
+def parse_header(buf):
+    if len(buf) < 8:
+        raise loxi.ProtocolError("too short to be an OpenFlow message")
+    return struct.unpack_from("!BBHL", buf)
+
+def parse_message(buf):
+    msg_ver, msg_type, msg_len, msg_xid = parse_header(buf)
+    if msg_ver != ofp.OFP_VERSION and msg_type != ofp.OFPT_HELLO:
+        raise loxi.ProtocolError("wrong OpenFlow version (expected %d, got %d)" % (ofp.OFP_VERSION, msg_ver))
+    if len(buf) != msg_len:
+        raise loxi.ProtocolError("incorrect message size")
+    return message.unpack(loxi.generic_util.OFReader(buf))
diff --git a/Fabric/Utilities/src/python/loxi/of13/meter_band.py b/Fabric/Utilities/src/python/loxi/of13/meter_band.py
new file mode 100644
index 0000000..f0ed683
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of13/meter_band.py
@@ -0,0 +1,275 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of13']
+
+class meter_band(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = meter_band.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = meter_band()
+        obj.type = reader.read("!H")[0]
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("meter_band {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class drop(meter_band):
+    type = 1
+
+    def __init__(self, rate=None, burst_size=None):
+        if rate != None:
+            self.rate = rate
+        else:
+            self.rate = 0
+        if burst_size != None:
+            self.burst_size = burst_size
+        else:
+            self.burst_size = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.rate))
+        packed.append(struct.pack("!L", self.burst_size))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = drop()
+        _type = reader.read("!H")[0]
+        assert(_type == 1)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.rate = reader.read("!L")[0]
+        obj.burst_size = reader.read("!L")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.rate != other.rate: return False
+        if self.burst_size != other.burst_size: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("drop {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("rate = ");
+                q.text("%#x" % self.rate)
+                q.text(","); q.breakable()
+                q.text("burst_size = ");
+                q.text("%#x" % self.burst_size)
+            q.breakable()
+        q.text('}')
+
+meter_band.subtypes[1] = drop
+
+class dscp_remark(meter_band):
+    type = 2
+
+    def __init__(self, rate=None, burst_size=None, prec_level=None):
+        if rate != None:
+            self.rate = rate
+        else:
+            self.rate = 0
+        if burst_size != None:
+            self.burst_size = burst_size
+        else:
+            self.burst_size = 0
+        if prec_level != None:
+            self.prec_level = prec_level
+        else:
+            self.prec_level = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.rate))
+        packed.append(struct.pack("!L", self.burst_size))
+        packed.append(struct.pack("!B", self.prec_level))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = dscp_remark()
+        _type = reader.read("!H")[0]
+        assert(_type == 2)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.rate = reader.read("!L")[0]
+        obj.burst_size = reader.read("!L")[0]
+        obj.prec_level = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.rate != other.rate: return False
+        if self.burst_size != other.burst_size: return False
+        if self.prec_level != other.prec_level: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("dscp_remark {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("rate = ");
+                q.text("%#x" % self.rate)
+                q.text(","); q.breakable()
+                q.text("burst_size = ");
+                q.text("%#x" % self.burst_size)
+                q.text(","); q.breakable()
+                q.text("prec_level = ");
+                q.text("%#x" % self.prec_level)
+            q.breakable()
+        q.text('}')
+
+meter_band.subtypes[2] = dscp_remark
+
+class experimenter(meter_band):
+    type = 65535
+
+    def __init__(self, rate=None, burst_size=None, experimenter=None):
+        if rate != None:
+            self.rate = rate
+        else:
+            self.rate = 0
+        if burst_size != None:
+            self.burst_size = burst_size
+        else:
+            self.burst_size = 0
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.rate))
+        packed.append(struct.pack("!L", self.burst_size))
+        packed.append(struct.pack("!L", self.experimenter))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = experimenter()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.rate = reader.read("!L")[0]
+        obj.burst_size = reader.read("!L")[0]
+        obj.experimenter = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.rate != other.rate: return False
+        if self.burst_size != other.burst_size: return False
+        if self.experimenter != other.experimenter: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("rate = ");
+                q.text("%#x" % self.rate)
+                q.text(","); q.breakable()
+                q.text("burst_size = ");
+                q.text("%#x" % self.burst_size)
+                q.text(","); q.breakable()
+                q.text("experimenter = ");
+                q.text("%#x" % self.experimenter)
+            q.breakable()
+        q.text('}')
+
+meter_band.subtypes[65535] = experimenter
+
+
diff --git a/Fabric/Utilities/src/python/loxi/of13/oxm.py b/Fabric/Utilities/src/python/loxi/of13/oxm.py
new file mode 100755
index 0000000..a2c0a23
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of13/oxm.py
@@ -0,0 +1,6329 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of13']
+
+class oxm(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type_len=None):
+        if type_len != None:
+            self.type_len = type_len
+        else:
+            self.type_len = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 0)
+        subclass = oxm.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = oxm()
+        obj.type_len = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type_len != other.type_len: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("oxm {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class arp_op(oxm):
+    type_len = 2147494402
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = arp_op()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147494402)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("arp_op {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147494402] = arp_op
+
+class arp_op_masked(oxm):
+    type_len = 2147494660
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        packed.append(struct.pack("!H", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = arp_op_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147494660)
+        obj.value = reader.read("!H")[0]
+        obj.value_mask = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("arp_op_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147494660] = arp_op_masked
+
+class arp_sha(oxm):
+    type_len = 2147495942
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = arp_sha()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147495942)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("arp_sha {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147495942] = arp_sha
+
+class arp_sha_masked(oxm):
+    type_len = 2147496204
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        packed.append(struct.pack("!6B", *self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = arp_sha_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147496204)
+        obj.value = list(reader.read('!6B'))
+        obj.value_mask = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("arp_sha_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_mac(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147496204] = arp_sha_masked
+
+class arp_spa(oxm):
+    type_len = 2147494916
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = arp_spa()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147494916)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("arp_spa {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147494916] = arp_spa
+
+class arp_spa_masked(oxm):
+    type_len = 2147495176
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = arp_spa_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147495176)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("arp_spa_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147495176] = arp_spa_masked
+
+class arp_tha(oxm):
+    type_len = 2147496454
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = arp_tha()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147496454)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("arp_tha {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147496454] = arp_tha
+
+class arp_tha_masked(oxm):
+    type_len = 2147496716
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        packed.append(struct.pack("!6B", *self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = arp_tha_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147496716)
+        obj.value = list(reader.read('!6B'))
+        obj.value_mask = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("arp_tha_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_mac(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147496716] = arp_tha_masked
+
+class arp_tpa(oxm):
+    type_len = 2147495428
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = arp_tpa()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147495428)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("arp_tpa {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147495428] = arp_tpa
+
+class arp_tpa_masked(oxm):
+    type_len = 2147495688
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = arp_tpa_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147495688)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("arp_tpa_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147495688] = arp_tpa_masked
+
+class bsn_egr_port_group_id(oxm):
+    type_len = 200196
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_egr_port_group_id()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 200196)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_egr_port_group_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[200196] = bsn_egr_port_group_id
+
+class bsn_egr_port_group_id_masked(oxm):
+    type_len = 200456
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_egr_port_group_id_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 200456)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_egr_port_group_id_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[200456] = bsn_egr_port_group_id_masked
+
+class bsn_global_vrf_allowed(oxm):
+    type_len = 198145
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_global_vrf_allowed()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 198145)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_global_vrf_allowed {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[198145] = bsn_global_vrf_allowed
+
+class bsn_global_vrf_allowed_masked(oxm):
+    type_len = 198402
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        packed.append(struct.pack("!B", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_global_vrf_allowed_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 198402)
+        obj.value = reader.read("!B")[0]
+        obj.value_mask = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_global_vrf_allowed_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[198402] = bsn_global_vrf_allowed_masked
+
+class bsn_in_ports_128(oxm):
+    type_len = 196624
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = set()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(util.pack_bitmap_128(self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_in_ports_128()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 196624)
+        obj.value = util.unpack_bitmap_128(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_in_ports_128 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[196624] = bsn_in_ports_128
+
+class bsn_in_ports_128_masked(oxm):
+    type_len = 196896
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = set()
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = set()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(util.pack_bitmap_128(self.value))
+        packed.append(util.pack_bitmap_128(self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_in_ports_128_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 196896)
+        obj.value = util.unpack_bitmap_128(reader)
+        obj.value_mask = util.unpack_bitmap_128(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_in_ports_128_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.pp(self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[196896] = bsn_in_ports_128_masked
+
+class bsn_in_ports_512(oxm):
+    type_len = 206400
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = set()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(util.pack_bitmap_512(self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_in_ports_512()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 206400)
+        obj.value = util.unpack_bitmap_512(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_in_ports_512 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[206400] = bsn_in_ports_512
+
+class bsn_in_ports_512_masked(oxm):
+    type_len = 206720
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = set()
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = set()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(util.pack_bitmap_512(self.value))
+        packed.append(util.pack_bitmap_512(self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_in_ports_512_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 206720)
+        obj.value = util.unpack_bitmap_512(reader)
+        obj.value_mask = util.unpack_bitmap_512(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_in_ports_512_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.pp(self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[206720] = bsn_in_ports_512_masked
+
+class bsn_ingress_port_group_id(oxm):
+    type_len = 206852
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_ingress_port_group_id()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 206852)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_ingress_port_group_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[206852] = bsn_ingress_port_group_id
+
+class bsn_ingress_port_group_id_masked(oxm):
+    type_len = 207112
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_ingress_port_group_id_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 207112)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_ingress_port_group_id_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[207112] = bsn_ingress_port_group_id_masked
+
+class bsn_inner_eth_dst(oxm):
+    type_len = 207878
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_inner_eth_dst()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 207878)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_inner_eth_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[207878] = bsn_inner_eth_dst
+
+class bsn_inner_eth_dst_masked(oxm):
+    type_len = 208140
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        packed.append(struct.pack("!6B", *self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_inner_eth_dst_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 208140)
+        obj.value = list(reader.read('!6B'))
+        obj.value_mask = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_inner_eth_dst_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_mac(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[208140] = bsn_inner_eth_dst_masked
+
+class bsn_inner_eth_src(oxm):
+    type_len = 208390
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_inner_eth_src()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 208390)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_inner_eth_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[208390] = bsn_inner_eth_src
+
+class bsn_inner_eth_src_masked(oxm):
+    type_len = 208652
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        packed.append(struct.pack("!6B", *self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_inner_eth_src_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 208652)
+        obj.value = list(reader.read('!6B'))
+        obj.value_mask = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_inner_eth_src_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_mac(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[208652] = bsn_inner_eth_src_masked
+
+class bsn_inner_vlan_vid(oxm):
+    type_len = 208898
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_inner_vlan_vid()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 208898)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_inner_vlan_vid {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[208898] = bsn_inner_vlan_vid
+
+class bsn_inner_vlan_vid_masked(oxm):
+    type_len = 209156
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        packed.append(struct.pack("!H", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_inner_vlan_vid_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 209156)
+        obj.value = reader.read("!H")[0]
+        obj.value_mask = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_inner_vlan_vid_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[209156] = bsn_inner_vlan_vid_masked
+
+class bsn_l2_cache_hit(oxm):
+    type_len = 205825
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_l2_cache_hit()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 205825)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_l2_cache_hit {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[205825] = bsn_l2_cache_hit
+
+class bsn_l2_cache_hit_masked(oxm):
+    type_len = 206082
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        packed.append(struct.pack("!B", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_l2_cache_hit_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 206082)
+        obj.value = reader.read("!B")[0]
+        obj.value_mask = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_l2_cache_hit_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[206082] = bsn_l2_cache_hit_masked
+
+class bsn_l3_dst_class_id(oxm):
+    type_len = 199684
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_l3_dst_class_id()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 199684)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_l3_dst_class_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[199684] = bsn_l3_dst_class_id
+
+class bsn_l3_dst_class_id_masked(oxm):
+    type_len = 199944
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_l3_dst_class_id_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 199944)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_l3_dst_class_id_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[199944] = bsn_l3_dst_class_id_masked
+
+class bsn_l3_interface_class_id(oxm):
+    type_len = 198660
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_l3_interface_class_id()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 198660)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_l3_interface_class_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[198660] = bsn_l3_interface_class_id
+
+class bsn_l3_interface_class_id_masked(oxm):
+    type_len = 198920
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_l3_interface_class_id_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 198920)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_l3_interface_class_id_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[198920] = bsn_l3_interface_class_id_masked
+
+class bsn_l3_src_class_id(oxm):
+    type_len = 199172
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_l3_src_class_id()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 199172)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_l3_src_class_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[199172] = bsn_l3_src_class_id
+
+class bsn_l3_src_class_id_masked(oxm):
+    type_len = 199432
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_l3_src_class_id_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 199432)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_l3_src_class_id_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[199432] = bsn_l3_src_class_id_masked
+
+class bsn_lag_id(oxm):
+    type_len = 197124
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_lag_id()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 197124)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_lag_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[197124] = bsn_lag_id
+
+class bsn_lag_id_masked(oxm):
+    type_len = 197384
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_lag_id_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 197384)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_lag_id_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[197384] = bsn_lag_id_masked
+
+class bsn_tcp_flags(oxm):
+    type_len = 204802
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_tcp_flags()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 204802)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_tcp_flags {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[204802] = bsn_tcp_flags
+
+class bsn_tcp_flags_masked(oxm):
+    type_len = 205060
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        packed.append(struct.pack("!H", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_tcp_flags_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 205060)
+        obj.value = reader.read("!H")[0]
+        obj.value_mask = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_tcp_flags_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[205060] = bsn_tcp_flags_masked
+
+class bsn_udf0(oxm):
+    type_len = 200708
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf0()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 200708)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf0 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[200708] = bsn_udf0
+
+class bsn_udf0_masked(oxm):
+    type_len = 200968
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf0_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 200968)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf0_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[200968] = bsn_udf0_masked
+
+class bsn_udf1(oxm):
+    type_len = 201220
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf1()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 201220)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf1 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[201220] = bsn_udf1
+
+class bsn_udf1_masked(oxm):
+    type_len = 201480
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf1_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 201480)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf1_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[201480] = bsn_udf1_masked
+
+class bsn_udf2(oxm):
+    type_len = 201732
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf2()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 201732)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf2 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[201732] = bsn_udf2
+
+class bsn_udf2_masked(oxm):
+    type_len = 201992
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf2_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 201992)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf2_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[201992] = bsn_udf2_masked
+
+class bsn_udf3(oxm):
+    type_len = 202244
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf3()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 202244)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf3 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[202244] = bsn_udf3
+
+class bsn_udf3_masked(oxm):
+    type_len = 202504
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf3_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 202504)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf3_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[202504] = bsn_udf3_masked
+
+class bsn_udf4(oxm):
+    type_len = 202756
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf4()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 202756)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf4 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[202756] = bsn_udf4
+
+class bsn_udf4_masked(oxm):
+    type_len = 203016
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf4_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 203016)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf4_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[203016] = bsn_udf4_masked
+
+class bsn_udf5(oxm):
+    type_len = 203268
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf5()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 203268)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf5 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[203268] = bsn_udf5
+
+class bsn_udf5_masked(oxm):
+    type_len = 203528
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf5_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 203528)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf5_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[203528] = bsn_udf5_masked
+
+class bsn_udf6(oxm):
+    type_len = 203780
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf6()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 203780)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf6 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[203780] = bsn_udf6
+
+class bsn_udf6_masked(oxm):
+    type_len = 204040
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf6_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 204040)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf6_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[204040] = bsn_udf6_masked
+
+class bsn_udf7(oxm):
+    type_len = 204292
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf7()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 204292)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf7 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[204292] = bsn_udf7
+
+class bsn_udf7_masked(oxm):
+    type_len = 204552
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf7_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 204552)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf7_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[204552] = bsn_udf7_masked
+
+class bsn_vlan_xlate_port_group_id(oxm):
+    type_len = 205316
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vlan_xlate_port_group_id()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 205316)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vlan_xlate_port_group_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[205316] = bsn_vlan_xlate_port_group_id
+
+class bsn_vlan_xlate_port_group_id_masked(oxm):
+    type_len = 205576
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vlan_xlate_port_group_id_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 205576)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vlan_xlate_port_group_id_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[205576] = bsn_vlan_xlate_port_group_id_masked
+
+class bsn_vrf(oxm):
+    type_len = 197636
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vrf()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 197636)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vrf {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[197636] = bsn_vrf
+
+class bsn_vrf_masked(oxm):
+    type_len = 197896
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vrf_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 197896)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vrf_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[197896] = bsn_vrf_masked
+
+class bsn_vxlan_network_id(oxm):
+    type_len = 207364
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vxlan_network_id()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 207364)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vxlan_network_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[207364] = bsn_vxlan_network_id
+
+class bsn_vxlan_network_id_masked(oxm):
+    type_len = 207624
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vxlan_network_id_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 207624)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vxlan_network_id_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[207624] = bsn_vxlan_network_id_masked
+
+class eth_dst(oxm):
+    type_len = 2147485190
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = eth_dst()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147485190)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("eth_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147485190] = eth_dst
+
+class eth_dst_masked(oxm):
+    type_len = 2147485452
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        packed.append(struct.pack("!6B", *self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = eth_dst_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147485452)
+        obj.value = list(reader.read('!6B'))
+        obj.value_mask = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("eth_dst_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_mac(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147485452] = eth_dst_masked
+
+class eth_src(oxm):
+    type_len = 2147485702
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = eth_src()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147485702)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("eth_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147485702] = eth_src
+
+class eth_src_masked(oxm):
+    type_len = 2147485964
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        packed.append(struct.pack("!6B", *self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = eth_src_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147485964)
+        obj.value = list(reader.read('!6B'))
+        obj.value_mask = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("eth_src_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_mac(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147485964] = eth_src_masked
+
+class eth_type(oxm):
+    type_len = 2147486210
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = eth_type()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147486210)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("eth_type {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147486210] = eth_type
+
+class eth_type_masked(oxm):
+    type_len = 2147486468
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        packed.append(struct.pack("!H", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = eth_type_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147486468)
+        obj.value = reader.read("!H")[0]
+        obj.value_mask = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("eth_type_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147486468] = eth_type_masked
+
+class icmpv4_code(oxm):
+    type_len = 2147493889
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = icmpv4_code()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147493889)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("icmpv4_code {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147493889] = icmpv4_code
+
+class icmpv4_code_masked(oxm):
+    type_len = 2147494146
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        packed.append(struct.pack("!B", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = icmpv4_code_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147494146)
+        obj.value = reader.read("!B")[0]
+        obj.value_mask = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("icmpv4_code_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147494146] = icmpv4_code_masked
+
+class icmpv4_type(oxm):
+    type_len = 2147493377
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = icmpv4_type()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147493377)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("icmpv4_type {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147493377] = icmpv4_type
+
+class icmpv4_type_masked(oxm):
+    type_len = 2147493634
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        packed.append(struct.pack("!B", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = icmpv4_type_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147493634)
+        obj.value = reader.read("!B")[0]
+        obj.value_mask = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("icmpv4_type_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147493634] = icmpv4_type_masked
+
+class icmpv6_code(oxm):
+    type_len = 2147499009
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = icmpv6_code()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147499009)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("icmpv6_code {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147499009] = icmpv6_code
+
+class icmpv6_code_masked(oxm):
+    type_len = 2147499266
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        packed.append(struct.pack("!B", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = icmpv6_code_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147499266)
+        obj.value = reader.read("!B")[0]
+        obj.value_mask = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("icmpv6_code_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147499266] = icmpv6_code_masked
+
+class icmpv6_type(oxm):
+    type_len = 2147498497
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = icmpv6_type()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147498497)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("icmpv6_type {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147498497] = icmpv6_type
+
+class icmpv6_type_masked(oxm):
+    type_len = 2147498754
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        packed.append(struct.pack("!B", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = icmpv6_type_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147498754)
+        obj.value = reader.read("!B")[0]
+        obj.value_mask = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("icmpv6_type_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147498754] = icmpv6_type_masked
+
+class in_phy_port(oxm):
+    type_len = 2147484164
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(util.pack_port_no(self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = in_phy_port()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147484164)
+        obj.value = util.unpack_port_no(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("in_phy_port {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_port(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147484164] = in_phy_port
+
+class in_phy_port_masked(oxm):
+    type_len = 2147484424
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(util.pack_port_no(self.value))
+        packed.append(util.pack_port_no(self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = in_phy_port_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147484424)
+        obj.value = util.unpack_port_no(reader)
+        obj.value_mask = util.unpack_port_no(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("in_phy_port_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_port(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_port(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147484424] = in_phy_port_masked
+
+class in_port(oxm):
+    type_len = 2147483652
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(util.pack_port_no(self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = in_port()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147483652)
+        obj.value = util.unpack_port_no(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("in_port {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_port(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147483652] = in_port
+
+class in_port_masked(oxm):
+    type_len = 2147483912
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(util.pack_port_no(self.value))
+        packed.append(util.pack_port_no(self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = in_port_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147483912)
+        obj.value = util.unpack_port_no(reader)
+        obj.value_mask = util.unpack_port_no(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("in_port_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_port(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_port(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147483912] = in_port_masked
+
+class ip_dscp(oxm):
+    type_len = 2147487745
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ip_dscp()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147487745)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ip_dscp {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147487745] = ip_dscp
+
+class ip_dscp_masked(oxm):
+    type_len = 2147488002
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        packed.append(struct.pack("!B", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ip_dscp_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147488002)
+        obj.value = reader.read("!B")[0]
+        obj.value_mask = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ip_dscp_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147488002] = ip_dscp_masked
+
+class ip_ecn(oxm):
+    type_len = 2147488257
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ip_ecn()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147488257)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ip_ecn {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147488257] = ip_ecn
+
+class ip_ecn_masked(oxm):
+    type_len = 2147488514
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        packed.append(struct.pack("!B", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ip_ecn_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147488514)
+        obj.value = reader.read("!B")[0]
+        obj.value_mask = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ip_ecn_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147488514] = ip_ecn_masked
+
+class ip_proto(oxm):
+    type_len = 2147488769
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ip_proto()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147488769)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ip_proto {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147488769] = ip_proto
+
+class ip_proto_masked(oxm):
+    type_len = 2147489026
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        packed.append(struct.pack("!B", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ip_proto_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147489026)
+        obj.value = reader.read("!B")[0]
+        obj.value_mask = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ip_proto_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147489026] = ip_proto_masked
+
+class ipv4_dst(oxm):
+    type_len = 2147489796
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv4_dst()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147489796)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv4_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147489796] = ipv4_dst
+
+class ipv4_dst_masked(oxm):
+    type_len = 2147490056
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv4_dst_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147490056)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv4_dst_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_ipv4(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147490056] = ipv4_dst_masked
+
+class ipv4_src(oxm):
+    type_len = 2147489284
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv4_src()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147489284)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv4_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147489284] = ipv4_src
+
+class ipv4_src_masked(oxm):
+    type_len = 2147489544
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv4_src_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147489544)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv4_src_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_ipv4(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147489544] = ipv4_src_masked
+
+class ipv6_dst(oxm):
+    type_len = 2147497488
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!16s", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_dst()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147497488)
+        obj.value = reader.read('!16s')[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147497488] = ipv6_dst
+
+class ipv6_dst_masked(oxm):
+    type_len = 2147497760
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!16s", self.value))
+        packed.append(struct.pack("!16s", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_dst_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147497760)
+        obj.value = reader.read('!16s')[0]
+        obj.value_mask = reader.read('!16s')[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_dst_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.pp(self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147497760] = ipv6_dst_masked
+
+class ipv6_exthdr(oxm):
+    type_len = 2147503618
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_exthdr()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147503618)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_exthdr {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147503618] = ipv6_exthdr
+
+class ipv6_exthdr_masked(oxm):
+    type_len = 2147503876
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        packed.append(struct.pack("!H", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_exthdr_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147503876)
+        obj.value = reader.read("!H")[0]
+        obj.value_mask = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_exthdr_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147503876] = ipv6_exthdr_masked
+
+class ipv6_flabel(oxm):
+    type_len = 2147497988
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_flabel()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147497988)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_flabel {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147497988] = ipv6_flabel
+
+class ipv6_flabel_masked(oxm):
+    type_len = 2147498248
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_flabel_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147498248)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_flabel_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147498248] = ipv6_flabel_masked
+
+class ipv6_nd_sll(oxm):
+    type_len = 2147500038
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_nd_sll()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147500038)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_nd_sll {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147500038] = ipv6_nd_sll
+
+class ipv6_nd_sll_masked(oxm):
+    type_len = 2147500300
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        packed.append(struct.pack("!6B", *self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_nd_sll_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147500300)
+        obj.value = list(reader.read('!6B'))
+        obj.value_mask = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_nd_sll_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_mac(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147500300] = ipv6_nd_sll_masked
+
+class ipv6_nd_target(oxm):
+    type_len = 2147499536
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!16s", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_nd_target()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147499536)
+        obj.value = reader.read('!16s')[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_nd_target {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147499536] = ipv6_nd_target
+
+class ipv6_nd_target_masked(oxm):
+    type_len = 2147499808
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!16s", self.value))
+        packed.append(struct.pack("!16s", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_nd_target_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147499808)
+        obj.value = reader.read('!16s')[0]
+        obj.value_mask = reader.read('!16s')[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_nd_target_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.pp(self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147499808] = ipv6_nd_target_masked
+
+class ipv6_nd_tll(oxm):
+    type_len = 2147500550
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_nd_tll()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147500550)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_nd_tll {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147500550] = ipv6_nd_tll
+
+class ipv6_nd_tll_masked(oxm):
+    type_len = 2147500812
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        packed.append(struct.pack("!6B", *self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_nd_tll_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147500812)
+        obj.value = list(reader.read('!6B'))
+        obj.value_mask = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_nd_tll_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_mac(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147500812] = ipv6_nd_tll_masked
+
+class ipv6_src(oxm):
+    type_len = 2147496976
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!16s", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_src()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147496976)
+        obj.value = reader.read('!16s')[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147496976] = ipv6_src
+
+class ipv6_src_masked(oxm):
+    type_len = 2147497248
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!16s", self.value))
+        packed.append(struct.pack("!16s", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_src_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147497248)
+        obj.value = reader.read('!16s')[0]
+        obj.value_mask = reader.read('!16s')[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_src_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.pp(self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147497248] = ipv6_src_masked
+
+class metadata(oxm):
+    type_len = 2147484680
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!Q", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = metadata()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147484680)
+        obj.value = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("metadata {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147484680] = metadata
+
+class metadata_masked(oxm):
+    type_len = 2147484944
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!Q", self.value))
+        packed.append(struct.pack("!Q", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = metadata_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147484944)
+        obj.value = reader.read("!Q")[0]
+        obj.value_mask = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("metadata_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147484944] = metadata_masked
+
+class mpls_bos(oxm):
+    type_len = 2147502081
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = mpls_bos()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147502081)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("mpls_bos {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147502081] = mpls_bos
+
+class mpls_bos_masked(oxm):
+    type_len = 2147502338
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        packed.append(struct.pack("!B", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = mpls_bos_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147502338)
+        obj.value = reader.read("!B")[0]
+        obj.value_mask = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("mpls_bos_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147502338] = mpls_bos_masked
+
+class mpls_label(oxm):
+    type_len = 2147501060
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = mpls_label()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147501060)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("mpls_label {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147501060] = mpls_label
+
+class mpls_label_masked(oxm):
+    type_len = 2147501320
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = mpls_label_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147501320)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("mpls_label_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147501320] = mpls_label_masked
+
+class mpls_tc(oxm):
+    type_len = 2147501569
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = mpls_tc()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147501569)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("mpls_tc {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147501569] = mpls_tc
+
+class mpls_tc_masked(oxm):
+    type_len = 2147501826
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        packed.append(struct.pack("!B", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = mpls_tc_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147501826)
+        obj.value = reader.read("!B")[0]
+        obj.value_mask = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("mpls_tc_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147501826] = mpls_tc_masked
+
+class sctp_dst(oxm):
+    type_len = 2147492866
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = sctp_dst()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147492866)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("sctp_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147492866] = sctp_dst
+
+class sctp_dst_masked(oxm):
+    type_len = 2147493124
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        packed.append(struct.pack("!H", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = sctp_dst_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147493124)
+        obj.value = reader.read("!H")[0]
+        obj.value_mask = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("sctp_dst_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147493124] = sctp_dst_masked
+
+class sctp_src(oxm):
+    type_len = 2147492354
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = sctp_src()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147492354)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("sctp_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147492354] = sctp_src
+
+class sctp_src_masked(oxm):
+    type_len = 2147492612
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        packed.append(struct.pack("!H", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = sctp_src_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147492612)
+        obj.value = reader.read("!H")[0]
+        obj.value_mask = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("sctp_src_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147492612] = sctp_src_masked
+
+class tcp_dst(oxm):
+    type_len = 2147490818
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = tcp_dst()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147490818)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("tcp_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147490818] = tcp_dst
+
+class tcp_dst_masked(oxm):
+    type_len = 2147491076
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        packed.append(struct.pack("!H", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = tcp_dst_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147491076)
+        obj.value = reader.read("!H")[0]
+        obj.value_mask = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("tcp_dst_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147491076] = tcp_dst_masked
+
+class tcp_src(oxm):
+    type_len = 2147490306
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = tcp_src()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147490306)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("tcp_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147490306] = tcp_src
+
+class tcp_src_masked(oxm):
+    type_len = 2147490564
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        packed.append(struct.pack("!H", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = tcp_src_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147490564)
+        obj.value = reader.read("!H")[0]
+        obj.value_mask = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("tcp_src_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147490564] = tcp_src_masked
+
+class tunnel_id(oxm):
+    type_len = 2147503112
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!Q", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = tunnel_id()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147503112)
+        obj.value = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("tunnel_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147503112] = tunnel_id
+
+class tunnel_id_masked(oxm):
+    type_len = 2147503376
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!Q", self.value))
+        packed.append(struct.pack("!Q", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = tunnel_id_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147503376)
+        obj.value = reader.read("!Q")[0]
+        obj.value_mask = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("tunnel_id_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147503376] = tunnel_id_masked
+
+class tunnel_ipv4_dst(oxm):
+    type_len = 81924
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = tunnel_ipv4_dst()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 81924)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("tunnel_ipv4_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[81924] = tunnel_ipv4_dst
+
+class tunnel_ipv4_dst_masked(oxm):
+    type_len = 82184
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = tunnel_ipv4_dst_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 82184)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("tunnel_ipv4_dst_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_ipv4(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[82184] = tunnel_ipv4_dst_masked
+
+class tunnel_ipv4_src(oxm):
+    type_len = 81412
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = tunnel_ipv4_src()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 81412)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("tunnel_ipv4_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[81412] = tunnel_ipv4_src
+
+class tunnel_ipv4_src_masked(oxm):
+    type_len = 81672
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = tunnel_ipv4_src_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 81672)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("tunnel_ipv4_src_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_ipv4(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[81672] = tunnel_ipv4_src_masked
+
+class udp_dst(oxm):
+    type_len = 2147491842
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = udp_dst()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147491842)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("udp_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147491842] = udp_dst
+
+class udp_dst_masked(oxm):
+    type_len = 2147492100
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        packed.append(struct.pack("!H", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = udp_dst_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147492100)
+        obj.value = reader.read("!H")[0]
+        obj.value_mask = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("udp_dst_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147492100] = udp_dst_masked
+
+class udp_src(oxm):
+    type_len = 2147491330
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = udp_src()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147491330)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("udp_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147491330] = udp_src
+
+class udp_src_masked(oxm):
+    type_len = 2147491588
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        packed.append(struct.pack("!H", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = udp_src_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147491588)
+        obj.value = reader.read("!H")[0]
+        obj.value_mask = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("udp_src_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147491588] = udp_src_masked
+
+class vlan_pcp(oxm):
+    type_len = 2147487233
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = vlan_pcp()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147487233)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("vlan_pcp {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147487233] = vlan_pcp
+
+class vlan_pcp_masked(oxm):
+    type_len = 2147487490
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        packed.append(struct.pack("!B", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = vlan_pcp_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147487490)
+        obj.value = reader.read("!B")[0]
+        obj.value_mask = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("vlan_pcp_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147487490] = vlan_pcp_masked
+
+class vlan_vid(oxm):
+    type_len = 2147486722
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = vlan_vid()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147486722)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("vlan_vid {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147486722] = vlan_vid
+
+class vlan_vid_masked(oxm):
+    type_len = 2147486980
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        packed.append(struct.pack("!H", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = vlan_vid_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147486980)
+        obj.value = reader.read("!H")[0]
+        obj.value_mask = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("vlan_vid_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147486980] = vlan_vid_masked
+
+OFDPA_EXPERIMETER =0x00001018
+
+OFDPA_EXP_TYPE_VRF          =1
+OFDPA_EXP_TYPE_TRAFFIC_CLASS=2
+OFDPA_EXP_TYPE_COLOR        =3
+OFDPA_EXP_TYPE_DEI          =4
+OFDPA_EXP_TYPE_QOS_INDEX    =5
+OFDPA_EXP_TYPE_LMEP_ID      =6
+OFDPA_EXP_TYPE_MPLS_TTL     =7
+OFDPA_EXP_TYPE_MPLS_L2_PORT =8
+OFDPA_EXP_TYPE_OVID         =10
+OFDPA_EXP_TYPE_MPLS_DATA_FIRST_NIBBLE=11,
+OFDPA_EXP_TYPE_ACH_CHANNEL  =12
+OFDPA_EXP_TYPE_NEXT_LABLE_IS_GAL=13
+OFDPA_EXP_TYPE_OAM_Y1731_MDL=14
+OFDPA_EXP_TYPE_OAM_Y1731_OPCODE=15
+OFDPA_EXP_TYPE_COLOR_ACTION_INDEX=16
+OFDPA_EXP_TYPE_TXFCL        =17
+OFDPA_EXP_TYPE_RXFCL        =18
+OFDPA_EXP_TYPE_MPLS_TYPE    = 23
+OFDPA_EXP_TYPE_RX_TIMESAMP  =19
+
+OFDPA_EXP_TYPE_ACTSET_OUTPUT=43
+OFDPA_EXP_TYPE_ALLOW_VLAN_TRANSLATION=24
+
+VPWS                        = 1
+TUNNEL_ID_BASE              = 0x10000
+TUNNEL_ID_BASE_CROSS_CONNECT = 0x20000
+L3_PHP                      = 32
+
+class exp1ByteValue(oxm):
+    type_len = 0xffff0005
+
+    def __init__(self, exp_type=0, value=None):
+        if value != None:
+            self.value = value
+            self.exp_type=exp_type
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len | (self.exp_type <<9)))
+        packed.append(struct.pack("!L", OFDPA_EXPERIMETER))
+        #packed.append(struct.pack("!H", self.exp_type))
+        packed.append(struct.pack("!b", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = exp1ByteValue()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 0xffff0007)
+        experimenter = reader.read("!L")[0]
+        assert(experimenter == OFDPA_EXPERIMETER)
+        obj.exp_type= reader.read("!H")[0]
+        obj.value= reader.read("!b")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.exp_type != other.exp_type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("exp1ByteValue {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[0xffff0007] = exp1ByteValue
+
+class exp2ByteValue(oxm):
+    type_len = 0xffff0006
+
+    def __init__(self, exp_type=0, value=None):
+        if value != None:
+            self.value = value
+            self.exp_type=exp_type
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len | (self.exp_type <<9)))
+        packed.append(struct.pack("!L", OFDPA_EXPERIMETER))
+        #packed.append(struct.pack("!H", self.exp_type))
+        packed.append(struct.pack("!H", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = exp2ByteValue()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 0xffff0008)
+        experimenter = reader.read("!L")[0]
+        assert(experimenter == OFDPA_EXPERIMETER)
+        obj.exp_type= reader.read("!H")[0]
+        obj.value= reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.exp_type != other.exp_type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("exp2ByteValue {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[0xffff0008] = exp2ByteValue
+
+class exp4ByteValue(oxm):
+    type_len = 0xffff0008
+
+    def __init__(self, exp_type=0, value=None, experimenter=OFDPA_EXPERIMETER):
+        if value != None:
+            self.value = value
+            self.exp_type=exp_type
+            self.experimenter = experimenter
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len | (self.exp_type <<9)))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = exp4ByteValue()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 0xffff000a)
+        experimenter = reader.read("!L")[0]
+        assert(experimenter == OFDPA_EXPERIMETER)
+        obj.exp_type= reader.read("!H")[0]
+        obj.value= reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.exp_type != other.exp_type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("exp4ByteValue {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[0xffff000a] = exp4ByteValue
+
+class exp4ByteReg( oxm ):
+    type_len = 0x80010000
+
+    def __init__( self, oxm_field=0 ):
+        self.oxm_field = oxm_field
+
+    def pack( self ):
+        packed = [ ]
+        packed.append( struct.pack( "!L", self.type_len | (self.oxm_field << 9) ) )
+        return ''.join( packed )
diff --git a/Fabric/Utilities/src/python/loxi/of13/util.py b/Fabric/Utilities/src/python/loxi/of13/util.py
new file mode 100644
index 0000000..fe23da1
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of13/util.py
@@ -0,0 +1,139 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+# Automatically generated by LOXI from template util.py
+# Do not modify
+
+import struct
+import loxi
+import const
+import common
+import action
+import instruction
+import oxm
+import action_id
+import instruction_id
+import meter_band
+
+def pretty_mac(mac):
+    return ':'.join(["%02x" % x for x in mac])
+
+def pretty_ipv4(v):
+    return "%d.%d.%d.%d" % ((v >> 24) & 0xFF, (v >> 16) & 0xFF, (v >> 8) & 0xFF, v & 0xFF)
+
+def pretty_flags(v, flag_names):
+    set_flags = []
+    for flag_name in flag_names:
+        flag_value = getattr(const, flag_name)
+        if v & flag_value == flag_value:
+            set_flags.append(flag_name)
+        elif v & flag_value:
+            set_flags.append('%s&%#x' % (flag_name, v & flag_value))
+        v &= ~flag_value
+    if v:
+        set_flags.append("%#x" % v)
+    return '|'.join(set_flags) or '0'
+
+
+def pretty_port(v):
+    named_ports = [(k,v2) for (k,v2) in const.__dict__.iteritems() if k.startswith('OFPP_')]
+    for (k, v2) in named_ports:
+        if v == v2:
+            return k
+    return v
+
+def pack_port_no(value):
+    return struct.pack("!L", value)
+
+def unpack_port_no(reader):
+    return reader.read("!L")[0]
+
+def pack_fm_cmd(value):
+    return struct.pack("!B", value)
+
+def unpack_fm_cmd(reader):
+    return reader.read("!B")[0]
+
+def init_wc_bmap():
+    return 0
+
+def pack_wc_bmap(value):
+    return struct.pack("!Q", value)
+
+def unpack_wc_bmap(reader):
+    return reader.read("!Q")[0]
+
+def init_match_bmap():
+    return 0
+
+def pack_match_bmap(value):
+    return struct.pack("!Q", value)
+
+def unpack_match_bmap(reader):
+    return reader.read("!Q")[0]
+
+MASK64 = (1 << 64) - 1
+
+def pack_bitmap_128(value):
+    x = 0l
+    for y in value:
+        x |= 1 << y
+    return struct.pack("!QQ", (x >> 64) & MASK64, x & MASK64)
+
+def unpack_bitmap_128(reader):
+    hi, lo = reader.read("!QQ")
+    x = (hi << 64) | lo
+    i = 0
+    value = set()
+    while x != 0:
+        if x & 1 == 1:
+            value.add(i)
+        i += 1
+        x >>= 1
+    return value
+
+def pack_bitmap_512(value):
+    words = [0] * 8
+    for v in value:
+        assert v < 512
+        words[7-v/64] |= 1 << (v % 64)
+    return struct.pack("!8Q", *words)
+
+def unpack_bitmap_512(reader):
+    words = reader.read("!8Q")
+    x = 0l
+    for word in words:
+        x <<= 64
+        x |= word
+    i = 0
+    value = set()
+    while x != 0:
+        if x & 1 == 1:
+            value.add(i)
+        i += 1
+        x >>= 1
+    return value
+
+def pack_checksum_128(value):
+    return struct.pack("!QQ", (value >> 64) & MASK64, value & MASK64)
+
+def unpack_checksum_128(reader):
+    hi, lo = reader.read("!QQ")
+    return (hi << 64) | lo
diff --git a/Fabric/Utilities/src/python/loxi/of14/__init__.py b/Fabric/Utilities/src/python/loxi/of14/__init__.py
new file mode 100644
index 0000000..a8105d6
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of14/__init__.py
@@ -0,0 +1,46 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template init.py
+# Do not modify
+
+import const
+import port_desc_prop
+import bsn_tlv
+import meter_band
+import table_mod_prop
+import instruction
+import queue_desc_prop
+import oxm
+import bundle_prop
+import common
+import instruction_id
+import action
+import role_prop
+import message
+import queue_stats_prop
+import port_stats_prop
+import port_mod_prop
+import async_config_prop
+import action_id
+from const import *
+from common import *
+from loxi import ProtocolError
diff --git a/Fabric/Utilities/src/python/loxi/of14/action.py b/Fabric/Utilities/src/python/loxi/of14/action.py
new file mode 100644
index 0000000..93dd3dc
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of14/action.py
@@ -0,0 +1,1301 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of14']
+
+class action(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = action.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = action()
+        obj.type = reader.read("!H")[0]
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("action {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class experimenter(action):
+    subtypes = {}
+
+    type = 65535
+
+    def __init__(self, experimenter=None, data=None):
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed.append(loxi.generic_util.pad_to(8, length))
+        length += len(packed[-1])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 4)
+        subclass = experimenter.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = experimenter()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.experimenter = reader.read("!L")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.experimenter != other.experimenter: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[65535] = experimenter
+
+class bsn(experimenter):
+    subtypes = {}
+
+    type = 65535
+    experimenter = 6035143
+
+    def __init__(self, subtype=None):
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 8)
+        subclass = bsn.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = bsn()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        obj.subtype = reader.read("!L")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+experimenter.subtypes[6035143] = bsn
+
+class bsn_checksum(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 4
+
+    def __init__(self, checksum=None):
+        if checksum != None:
+            self.checksum = checksum
+        else:
+            self.checksum = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(util.pack_checksum_128(self.checksum))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_checksum()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 4)
+        obj.checksum = util.unpack_checksum_128(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.checksum != other.checksum: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_checksum {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("checksum = ");
+                q.pp(self.checksum)
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[4] = bsn_checksum
+
+class bsn_gentable(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 5
+
+    def __init__(self, table_id=None, key=None):
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if key != None:
+            self.key = key
+        else:
+            self.key = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.table_id))
+        packed.append(loxi.generic_util.pack_list(self.key))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 5)
+        obj.table_id = reader.read("!L")[0]
+        obj.key = loxi.generic_util.unpack_list(reader, ofp.bsn_tlv.bsn_tlv.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.table_id != other.table_id: return False
+        if self.key != other.key: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("key = ");
+                q.pp(self.key)
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[5] = bsn_gentable
+
+class bsn_mirror(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 1
+
+    def __init__(self, dest_port=None, vlan_tag=None, copy_stage=None):
+        if dest_port != None:
+            self.dest_port = dest_port
+        else:
+            self.dest_port = 0
+        if vlan_tag != None:
+            self.vlan_tag = vlan_tag
+        else:
+            self.vlan_tag = 0
+        if copy_stage != None:
+            self.copy_stage = copy_stage
+        else:
+            self.copy_stage = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.dest_port))
+        packed.append(struct.pack("!L", self.vlan_tag))
+        packed.append(struct.pack("!B", self.copy_stage))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_mirror()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 1)
+        obj.dest_port = reader.read("!L")[0]
+        obj.vlan_tag = reader.read("!L")[0]
+        obj.copy_stage = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.dest_port != other.dest_port: return False
+        if self.vlan_tag != other.vlan_tag: return False
+        if self.copy_stage != other.copy_stage: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_mirror {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("dest_port = ");
+                q.text("%#x" % self.dest_port)
+                q.text(","); q.breakable()
+                q.text("vlan_tag = ");
+                q.text("%#x" % self.vlan_tag)
+                q.text(","); q.breakable()
+                q.text("copy_stage = ");
+                q.text("%#x" % self.copy_stage)
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[1] = bsn_mirror
+
+class bsn_set_tunnel_dst(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 2
+
+    def __init__(self, dst=None):
+        if dst != None:
+            self.dst = dst
+        else:
+            self.dst = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.dst))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_tunnel_dst()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 2)
+        obj.dst = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.dst != other.dst: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_tunnel_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("dst = ");
+                q.text("%#x" % self.dst)
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[2] = bsn_set_tunnel_dst
+
+class copy_ttl_in(action):
+    type = 12
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = copy_ttl_in()
+        _type = reader.read("!H")[0]
+        assert(_type == 12)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("copy_ttl_in {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action.subtypes[12] = copy_ttl_in
+
+class copy_ttl_out(action):
+    type = 11
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = copy_ttl_out()
+        _type = reader.read("!H")[0]
+        assert(_type == 11)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("copy_ttl_out {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action.subtypes[11] = copy_ttl_out
+
+class dec_mpls_ttl(action):
+    type = 16
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = dec_mpls_ttl()
+        _type = reader.read("!H")[0]
+        assert(_type == 16)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("dec_mpls_ttl {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action.subtypes[16] = dec_mpls_ttl
+
+class dec_nw_ttl(action):
+    type = 24
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = dec_nw_ttl()
+        _type = reader.read("!H")[0]
+        assert(_type == 24)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("dec_nw_ttl {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action.subtypes[24] = dec_nw_ttl
+
+class group(action):
+    type = 22
+
+    def __init__(self, group_id=None):
+        if group_id != None:
+            self.group_id = group_id
+        else:
+            self.group_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.group_id))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group()
+        _type = reader.read("!H")[0]
+        assert(_type == 22)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.group_id = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.group_id != other.group_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("group_id = ");
+                q.text("%#x" % self.group_id)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[22] = group
+
+class nicira(experimenter):
+    subtypes = {}
+
+    type = 65535
+    experimenter = 8992
+
+    def __init__(self, subtype=None):
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!H", self.subtype))
+        packed.append('\x00' * 2)
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 8)
+        subclass = nicira.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = nicira()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 8992)
+        obj.subtype = reader.read("!H")[0]
+        reader.skip(2)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("nicira {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+experimenter.subtypes[8992] = nicira
+
+class nicira_dec_ttl(nicira):
+    type = 65535
+    experimenter = 8992
+    subtype = 18
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!H", self.subtype))
+        packed.append('\x00' * 2)
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = nicira_dec_ttl()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 8992)
+        _subtype = reader.read("!H")[0]
+        assert(_subtype == 18)
+        reader.skip(2)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("nicira_dec_ttl {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+nicira.subtypes[18] = nicira_dec_ttl
+
+class output(action):
+    type = 0
+
+    def __init__(self, port=None, max_len=None):
+        if port != None:
+            self.port = port
+        else:
+            self.port = 0
+        if max_len != None:
+            self.max_len = max_len
+        else:
+            self.max_len = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(util.pack_port_no(self.port))
+        packed.append(struct.pack("!H", self.max_len))
+        packed.append('\x00' * 6)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = output()
+        _type = reader.read("!H")[0]
+        assert(_type == 0)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.port = util.unpack_port_no(reader)
+        obj.max_len = reader.read("!H")[0]
+        reader.skip(6)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.port != other.port: return False
+        if self.max_len != other.max_len: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("output {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("port = ");
+                q.text(util.pretty_port(self.port))
+                q.text(","); q.breakable()
+                q.text("max_len = ");
+                q.text("%#x" % self.max_len)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[0] = output
+
+class pop_mpls(action):
+    type = 20
+
+    def __init__(self, ethertype=None):
+        if ethertype != None:
+            self.ethertype = ethertype
+        else:
+            self.ethertype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!H", self.ethertype))
+        packed.append('\x00' * 2)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = pop_mpls()
+        _type = reader.read("!H")[0]
+        assert(_type == 20)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.ethertype = reader.read("!H")[0]
+        reader.skip(2)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.ethertype != other.ethertype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("pop_mpls {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("ethertype = ");
+                q.text("%#x" % self.ethertype)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[20] = pop_mpls
+
+class pop_pbb(action):
+    type = 27
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = pop_pbb()
+        _type = reader.read("!H")[0]
+        assert(_type == 27)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("pop_pbb {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action.subtypes[27] = pop_pbb
+
+class pop_vlan(action):
+    type = 18
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = pop_vlan()
+        _type = reader.read("!H")[0]
+        assert(_type == 18)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("pop_vlan {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action.subtypes[18] = pop_vlan
+
+class push_mpls(action):
+    type = 19
+
+    def __init__(self, ethertype=None):
+        if ethertype != None:
+            self.ethertype = ethertype
+        else:
+            self.ethertype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!H", self.ethertype))
+        packed.append('\x00' * 2)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = push_mpls()
+        _type = reader.read("!H")[0]
+        assert(_type == 19)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.ethertype = reader.read("!H")[0]
+        reader.skip(2)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.ethertype != other.ethertype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("push_mpls {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("ethertype = ");
+                q.text("%#x" % self.ethertype)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[19] = push_mpls
+
+class push_pbb(action):
+    type = 26
+
+    def __init__(self, ethertype=None):
+        if ethertype != None:
+            self.ethertype = ethertype
+        else:
+            self.ethertype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!H", self.ethertype))
+        packed.append('\x00' * 2)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = push_pbb()
+        _type = reader.read("!H")[0]
+        assert(_type == 26)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.ethertype = reader.read("!H")[0]
+        reader.skip(2)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.ethertype != other.ethertype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("push_pbb {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("ethertype = ");
+                q.text("%#x" % self.ethertype)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[26] = push_pbb
+
+class push_vlan(action):
+    type = 17
+
+    def __init__(self, ethertype=None):
+        if ethertype != None:
+            self.ethertype = ethertype
+        else:
+            self.ethertype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!H", self.ethertype))
+        packed.append('\x00' * 2)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = push_vlan()
+        _type = reader.read("!H")[0]
+        assert(_type == 17)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.ethertype = reader.read("!H")[0]
+        reader.skip(2)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.ethertype != other.ethertype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("push_vlan {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("ethertype = ");
+                q.text("%#x" % self.ethertype)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[17] = push_vlan
+
+class set_field(action):
+    type = 25
+
+    def __init__(self, field=None):
+        if field != None:
+            self.field = field
+        else:
+            self.field = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(self.field.pack())
+        length = sum([len(x) for x in packed])
+        packed.append(loxi.generic_util.pad_to(8, length))
+        length += len(packed[-1])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_field()
+        _type = reader.read("!H")[0]
+        assert(_type == 25)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.field = ofp.oxm.oxm.unpack(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.field != other.field: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_field {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("field = ");
+                q.pp(self.field)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[25] = set_field
+
+class set_mpls_ttl(action):
+    type = 15
+
+    def __init__(self, mpls_ttl=None):
+        if mpls_ttl != None:
+            self.mpls_ttl = mpls_ttl
+        else:
+            self.mpls_ttl = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!B", self.mpls_ttl))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_mpls_ttl()
+        _type = reader.read("!H")[0]
+        assert(_type == 15)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.mpls_ttl = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.mpls_ttl != other.mpls_ttl: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_mpls_ttl {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("mpls_ttl = ");
+                q.text("%#x" % self.mpls_ttl)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[15] = set_mpls_ttl
+
+class set_nw_ttl(action):
+    type = 23
+
+    def __init__(self, nw_ttl=None):
+        if nw_ttl != None:
+            self.nw_ttl = nw_ttl
+        else:
+            self.nw_ttl = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!B", self.nw_ttl))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_nw_ttl()
+        _type = reader.read("!H")[0]
+        assert(_type == 23)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.nw_ttl = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.nw_ttl != other.nw_ttl: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_nw_ttl {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("nw_ttl = ");
+                q.text("%#x" % self.nw_ttl)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[23] = set_nw_ttl
+
+class set_queue(action):
+    type = 21
+
+    def __init__(self, queue_id=None):
+        if queue_id != None:
+            self.queue_id = queue_id
+        else:
+            self.queue_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.queue_id))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_queue()
+        _type = reader.read("!H")[0]
+        assert(_type == 21)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.queue_id = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.queue_id != other.queue_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_queue {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("queue_id = ");
+                q.text("%#x" % self.queue_id)
+            q.breakable()
+        q.text('}')
+
+action.subtypes[21] = set_queue
+
+
diff --git a/Fabric/Utilities/src/python/loxi/of14/action_id.py b/Fabric/Utilities/src/python/loxi/of14/action_id.py
new file mode 100644
index 0000000..ee33666
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of14/action_id.py
@@ -0,0 +1,1082 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of14']
+
+class action_id(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = action_id.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = action_id()
+        obj.type = reader.read("!H")[0]
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("action_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class experimenter(action_id):
+    subtypes = {}
+
+    type = 65535
+
+    def __init__(self, experimenter=None):
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 4)
+        subclass = experimenter.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = experimenter()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.experimenter = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.experimenter != other.experimenter: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action_id.subtypes[65535] = experimenter
+
+class bsn(experimenter):
+    subtypes = {}
+
+    type = 65535
+    experimenter = 6035143
+
+    def __init__(self, subtype=None):
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 8)
+        subclass = bsn.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = bsn()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        obj.subtype = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+experimenter.subtypes[6035143] = bsn
+
+class bsn_checksum(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 4
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_checksum()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_checksum {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[4] = bsn_checksum
+
+class bsn_gentable(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 5
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 5)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[5] = bsn_gentable
+
+class bsn_mirror(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 1
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_mirror()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 1)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_mirror {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[1] = bsn_mirror
+
+class bsn_set_tunnel_dst(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 2
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_tunnel_dst()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 2)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_tunnel_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[2] = bsn_set_tunnel_dst
+
+class copy_ttl_in(action_id):
+    type = 12
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = copy_ttl_in()
+        _type = reader.read("!H")[0]
+        assert(_type == 12)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("copy_ttl_in {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action_id.subtypes[12] = copy_ttl_in
+
+class copy_ttl_out(action_id):
+    type = 11
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = copy_ttl_out()
+        _type = reader.read("!H")[0]
+        assert(_type == 11)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("copy_ttl_out {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action_id.subtypes[11] = copy_ttl_out
+
+class dec_mpls_ttl(action_id):
+    type = 16
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = dec_mpls_ttl()
+        _type = reader.read("!H")[0]
+        assert(_type == 16)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("dec_mpls_ttl {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action_id.subtypes[16] = dec_mpls_ttl
+
+class dec_nw_ttl(action_id):
+    type = 24
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = dec_nw_ttl()
+        _type = reader.read("!H")[0]
+        assert(_type == 24)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("dec_nw_ttl {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action_id.subtypes[24] = dec_nw_ttl
+
+class group(action_id):
+    type = 22
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group()
+        _type = reader.read("!H")[0]
+        assert(_type == 22)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action_id.subtypes[22] = group
+
+class nicira(experimenter):
+    subtypes = {}
+
+    type = 65535
+    experimenter = 8992
+
+    def __init__(self, subtype=None):
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!H", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 8)
+        subclass = nicira.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = nicira()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 8992)
+        obj.subtype = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("nicira {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+experimenter.subtypes[8992] = nicira
+
+class nicira_dec_ttl(nicira):
+    type = 65535
+    experimenter = 8992
+    subtype = 18
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!H", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = nicira_dec_ttl()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 8992)
+        _subtype = reader.read("!H")[0]
+        assert(_subtype == 18)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("nicira_dec_ttl {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+nicira.subtypes[18] = nicira_dec_ttl
+
+class output(action_id):
+    type = 0
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = output()
+        _type = reader.read("!H")[0]
+        assert(_type == 0)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("output {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action_id.subtypes[0] = output
+
+class pop_mpls(action_id):
+    type = 20
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = pop_mpls()
+        _type = reader.read("!H")[0]
+        assert(_type == 20)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("pop_mpls {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action_id.subtypes[20] = pop_mpls
+
+class pop_pbb(action_id):
+    type = 27
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = pop_pbb()
+        _type = reader.read("!H")[0]
+        assert(_type == 27)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("pop_pbb {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action_id.subtypes[27] = pop_pbb
+
+class pop_vlan(action_id):
+    type = 18
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = pop_vlan()
+        _type = reader.read("!H")[0]
+        assert(_type == 18)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("pop_vlan {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action_id.subtypes[18] = pop_vlan
+
+class push_mpls(action_id):
+    type = 19
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = push_mpls()
+        _type = reader.read("!H")[0]
+        assert(_type == 19)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("push_mpls {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action_id.subtypes[19] = push_mpls
+
+class push_pbb(action_id):
+    type = 26
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = push_pbb()
+        _type = reader.read("!H")[0]
+        assert(_type == 26)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("push_pbb {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action_id.subtypes[26] = push_pbb
+
+class push_vlan(action_id):
+    type = 17
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = push_vlan()
+        _type = reader.read("!H")[0]
+        assert(_type == 17)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("push_vlan {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action_id.subtypes[17] = push_vlan
+
+class set_field(action_id):
+    type = 25
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_field()
+        _type = reader.read("!H")[0]
+        assert(_type == 25)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_field {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action_id.subtypes[25] = set_field
+
+class set_mpls_ttl(action_id):
+    type = 15
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_mpls_ttl()
+        _type = reader.read("!H")[0]
+        assert(_type == 15)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_mpls_ttl {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action_id.subtypes[15] = set_mpls_ttl
+
+class set_nw_ttl(action_id):
+    type = 23
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_nw_ttl()
+        _type = reader.read("!H")[0]
+        assert(_type == 23)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_nw_ttl {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action_id.subtypes[23] = set_nw_ttl
+
+class set_queue(action_id):
+    type = 21
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_queue()
+        _type = reader.read("!H")[0]
+        assert(_type == 21)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_queue {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+action_id.subtypes[21] = set_queue
+
+
diff --git a/Fabric/Utilities/src/python/loxi/of14/async_config_prop.py b/Fabric/Utilities/src/python/loxi/of14/async_config_prop.py
new file mode 100644
index 0000000..f3539da
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of14/async_config_prop.py
@@ -0,0 +1,720 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of14']
+
+class async_config_prop(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = async_config_prop.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = async_config_prop()
+        obj.type = reader.read("!H")[0]
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("async_config_prop {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class experimenter_master(async_config_prop):
+    type = 65535
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = experimenter_master()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter_master {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+async_config_prop.subtypes[65535] = experimenter_master
+
+class experimenter_slave(async_config_prop):
+    type = 65534
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = experimenter_slave()
+        _type = reader.read("!H")[0]
+        assert(_type == 65534)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter_slave {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+async_config_prop.subtypes[65534] = experimenter_slave
+
+class flow_removed_master(async_config_prop):
+    type = 5
+
+    def __init__(self, mask=None):
+        if mask != None:
+            self.mask = mask
+        else:
+            self.mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.mask))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_removed_master()
+        _type = reader.read("!H")[0]
+        assert(_type == 5)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.mask != other.mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_removed_master {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("mask = ");
+                q.text("%#x" % self.mask)
+            q.breakable()
+        q.text('}')
+
+async_config_prop.subtypes[5] = flow_removed_master
+
+class flow_removed_slave(async_config_prop):
+    type = 4
+
+    def __init__(self, mask=None):
+        if mask != None:
+            self.mask = mask
+        else:
+            self.mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.mask))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_removed_slave()
+        _type = reader.read("!H")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.mask != other.mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_removed_slave {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("mask = ");
+                q.text("%#x" % self.mask)
+            q.breakable()
+        q.text('}')
+
+async_config_prop.subtypes[4] = flow_removed_slave
+
+class packet_in_master(async_config_prop):
+    type = 1
+
+    def __init__(self, mask=None):
+        if mask != None:
+            self.mask = mask
+        else:
+            self.mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.mask))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = packet_in_master()
+        _type = reader.read("!H")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.mask != other.mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("packet_in_master {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("mask = ");
+                q.text("%#x" % self.mask)
+            q.breakable()
+        q.text('}')
+
+async_config_prop.subtypes[1] = packet_in_master
+
+class packet_in_slave(async_config_prop):
+    type = 0
+
+    def __init__(self, mask=None):
+        if mask != None:
+            self.mask = mask
+        else:
+            self.mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.mask))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = packet_in_slave()
+        _type = reader.read("!H")[0]
+        assert(_type == 0)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.mask != other.mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("packet_in_slave {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("mask = ");
+                q.text("%#x" % self.mask)
+            q.breakable()
+        q.text('}')
+
+async_config_prop.subtypes[0] = packet_in_slave
+
+class port_status_master(async_config_prop):
+    type = 3
+
+    def __init__(self, mask=None):
+        if mask != None:
+            self.mask = mask
+        else:
+            self.mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.mask))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_status_master()
+        _type = reader.read("!H")[0]
+        assert(_type == 3)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.mask != other.mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_status_master {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("mask = ");
+                q.text("%#x" % self.mask)
+            q.breakable()
+        q.text('}')
+
+async_config_prop.subtypes[3] = port_status_master
+
+class port_status_slave(async_config_prop):
+    type = 2
+
+    def __init__(self, mask=None):
+        if mask != None:
+            self.mask = mask
+        else:
+            self.mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.mask))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_status_slave()
+        _type = reader.read("!H")[0]
+        assert(_type == 2)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.mask != other.mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_status_slave {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("mask = ");
+                q.text("%#x" % self.mask)
+            q.breakable()
+        q.text('}')
+
+async_config_prop.subtypes[2] = port_status_slave
+
+class requestforward_master(async_config_prop):
+    type = 11
+
+    def __init__(self, mask=None):
+        if mask != None:
+            self.mask = mask
+        else:
+            self.mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.mask))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = requestforward_master()
+        _type = reader.read("!H")[0]
+        assert(_type == 11)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.mask != other.mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("requestforward_master {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("mask = ");
+                q.text("%#x" % self.mask)
+            q.breakable()
+        q.text('}')
+
+async_config_prop.subtypes[11] = requestforward_master
+
+class requestforward_slave(async_config_prop):
+    type = 10
+
+    def __init__(self, mask=None):
+        if mask != None:
+            self.mask = mask
+        else:
+            self.mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.mask))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = requestforward_slave()
+        _type = reader.read("!H")[0]
+        assert(_type == 10)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.mask != other.mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("requestforward_slave {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("mask = ");
+                q.text("%#x" % self.mask)
+            q.breakable()
+        q.text('}')
+
+async_config_prop.subtypes[10] = requestforward_slave
+
+class role_status_master(async_config_prop):
+    type = 7
+
+    def __init__(self, mask=None):
+        if mask != None:
+            self.mask = mask
+        else:
+            self.mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.mask))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = role_status_master()
+        _type = reader.read("!H")[0]
+        assert(_type == 7)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.mask != other.mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("role_status_master {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("mask = ");
+                q.text("%#x" % self.mask)
+            q.breakable()
+        q.text('}')
+
+async_config_prop.subtypes[7] = role_status_master
+
+class role_status_slave(async_config_prop):
+    type = 6
+
+    def __init__(self, mask=None):
+        if mask != None:
+            self.mask = mask
+        else:
+            self.mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.mask))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = role_status_slave()
+        _type = reader.read("!H")[0]
+        assert(_type == 6)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.mask != other.mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("role_status_slave {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("mask = ");
+                q.text("%#x" % self.mask)
+            q.breakable()
+        q.text('}')
+
+async_config_prop.subtypes[6] = role_status_slave
+
+class table_status_master(async_config_prop):
+    type = 9
+
+    def __init__(self, mask=None):
+        if mask != None:
+            self.mask = mask
+        else:
+            self.mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.mask))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_status_master()
+        _type = reader.read("!H")[0]
+        assert(_type == 9)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.mask != other.mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_status_master {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("mask = ");
+                q.text("%#x" % self.mask)
+            q.breakable()
+        q.text('}')
+
+async_config_prop.subtypes[9] = table_status_master
+
+class table_status_slave(async_config_prop):
+    type = 8
+
+    def __init__(self, mask=None):
+        if mask != None:
+            self.mask = mask
+        else:
+            self.mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.mask))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_status_slave()
+        _type = reader.read("!H")[0]
+        assert(_type == 8)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.mask != other.mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_status_slave {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("mask = ");
+                q.text("%#x" % self.mask)
+            q.breakable()
+        q.text('}')
+
+async_config_prop.subtypes[8] = table_status_slave
+
+
diff --git a/Fabric/Utilities/src/python/loxi/of14/bsn_tlv.py b/Fabric/Utilities/src/python/loxi/of14/bsn_tlv.py
new file mode 100644
index 0000000..b61c6d4
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of14/bsn_tlv.py
@@ -0,0 +1,3881 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of14']
+
+class bsn_tlv(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = bsn_tlv.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = bsn_tlv()
+        obj.type = reader.read("!H")[0]
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_tlv {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class actor_key(bsn_tlv):
+    type = 44
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = actor_key()
+        _type = reader.read("!H")[0]
+        assert(_type == 44)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("actor_key {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[44] = actor_key
+
+class actor_port_num(bsn_tlv):
+    type = 43
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = actor_port_num()
+        _type = reader.read("!H")[0]
+        assert(_type == 43)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("actor_port_num {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[43] = actor_port_num
+
+class actor_port_priority(bsn_tlv):
+    type = 42
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = actor_port_priority()
+        _type = reader.read("!H")[0]
+        assert(_type == 42)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("actor_port_priority {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[42] = actor_port_priority
+
+class actor_state(bsn_tlv):
+    type = 53
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!B", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = actor_state()
+        _type = reader.read("!H")[0]
+        assert(_type == 53)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("actor_state {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[53] = actor_state
+
+class actor_system_mac(bsn_tlv):
+    type = 41
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!6B", *self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = actor_system_mac()
+        _type = reader.read("!H")[0]
+        assert(_type == 41)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("actor_system_mac {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[41] = actor_system_mac
+
+class actor_system_priority(bsn_tlv):
+    type = 40
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = actor_system_priority()
+        _type = reader.read("!H")[0]
+        assert(_type == 40)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("actor_system_priority {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[40] = actor_system_priority
+
+class anchor(bsn_tlv):
+    type = 81
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = anchor()
+        _type = reader.read("!H")[0]
+        assert(_type == 81)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("anchor {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[81] = anchor
+
+class broadcast_query_timeout(bsn_tlv):
+    type = 10
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = broadcast_query_timeout()
+        _type = reader.read("!H")[0]
+        assert(_type == 10)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("broadcast_query_timeout {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[10] = broadcast_query_timeout
+
+class bucket(bsn_tlv):
+    type = 64
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(loxi.generic_util.pack_list(self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bucket()
+        _type = reader.read("!H")[0]
+        assert(_type == 64)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = loxi.generic_util.unpack_list(reader, ofp.bsn_tlv.bsn_tlv.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bucket {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[64] = bucket
+
+class circuit_id(bsn_tlv):
+    type = 14
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(self.value)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = circuit_id()
+        _type = reader.read("!H")[0]
+        assert(_type == 14)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("circuit_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[14] = circuit_id
+
+class convergence_status(bsn_tlv):
+    type = 45
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!B", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = convergence_status()
+        _type = reader.read("!H")[0]
+        assert(_type == 45)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("convergence_status {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[45] = convergence_status
+
+class crc_enabled(bsn_tlv):
+    type = 22
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!B", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = crc_enabled()
+        _type = reader.read("!H")[0]
+        assert(_type == 22)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("crc_enabled {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[22] = crc_enabled
+
+class data(bsn_tlv):
+    type = 55
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(self.value)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = data()
+        _type = reader.read("!H")[0]
+        assert(_type == 55)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("data {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[55] = data
+
+class eth_dst(bsn_tlv):
+    type = 33
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!6B", *self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = eth_dst()
+        _type = reader.read("!H")[0]
+        assert(_type == 33)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("eth_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[33] = eth_dst
+
+class eth_src(bsn_tlv):
+    type = 32
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!6B", *self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = eth_src()
+        _type = reader.read("!H")[0]
+        assert(_type == 32)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("eth_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[32] = eth_src
+
+class external_gateway_ip(bsn_tlv):
+    type = 26
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = external_gateway_ip()
+        _type = reader.read("!H")[0]
+        assert(_type == 26)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("external_gateway_ip {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[26] = external_gateway_ip
+
+class external_gateway_mac(bsn_tlv):
+    type = 29
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!6B", *self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = external_gateway_mac()
+        _type = reader.read("!H")[0]
+        assert(_type == 29)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("external_gateway_mac {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[29] = external_gateway_mac
+
+class external_ip(bsn_tlv):
+    type = 23
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = external_ip()
+        _type = reader.read("!H")[0]
+        assert(_type == 23)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("external_ip {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[23] = external_ip
+
+class external_mac(bsn_tlv):
+    type = 24
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!6B", *self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = external_mac()
+        _type = reader.read("!H")[0]
+        assert(_type == 24)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("external_mac {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[24] = external_mac
+
+class external_netmask(bsn_tlv):
+    type = 25
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = external_netmask()
+        _type = reader.read("!H")[0]
+        assert(_type == 25)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("external_netmask {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[25] = external_netmask
+
+class generation_id(bsn_tlv):
+    type = 80
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!Q", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = generation_id()
+        _type = reader.read("!H")[0]
+        assert(_type == 80)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("generation_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[80] = generation_id
+
+class header_size(bsn_tlv):
+    type = 31
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = header_size()
+        _type = reader.read("!H")[0]
+        assert(_type == 31)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("header_size {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[31] = header_size
+
+class icmp_code(bsn_tlv):
+    type = 69
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!B", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = icmp_code()
+        _type = reader.read("!H")[0]
+        assert(_type == 69)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("icmp_code {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[69] = icmp_code
+
+class icmp_id(bsn_tlv):
+    type = 70
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = icmp_id()
+        _type = reader.read("!H")[0]
+        assert(_type == 70)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("icmp_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[70] = icmp_id
+
+class icmp_type(bsn_tlv):
+    type = 68
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!B", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = icmp_type()
+        _type = reader.read("!H")[0]
+        assert(_type == 68)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("icmp_type {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[68] = icmp_type
+
+class idle_notification(bsn_tlv):
+    type = 7
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = idle_notification()
+        _type = reader.read("!H")[0]
+        assert(_type == 7)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("idle_notification {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[7] = idle_notification
+
+class idle_time(bsn_tlv):
+    type = 5
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!Q", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = idle_time()
+        _type = reader.read("!H")[0]
+        assert(_type == 5)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("idle_time {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[5] = idle_time
+
+class idle_timeout(bsn_tlv):
+    type = 8
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = idle_timeout()
+        _type = reader.read("!H")[0]
+        assert(_type == 8)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("idle_timeout {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[8] = idle_timeout
+
+class igmp_snooping(bsn_tlv):
+    type = 78
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = igmp_snooping()
+        _type = reader.read("!H")[0]
+        assert(_type == 78)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("igmp_snooping {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[78] = igmp_snooping
+
+class internal_gateway_mac(bsn_tlv):
+    type = 28
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!6B", *self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = internal_gateway_mac()
+        _type = reader.read("!H")[0]
+        assert(_type == 28)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("internal_gateway_mac {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[28] = internal_gateway_mac
+
+class internal_mac(bsn_tlv):
+    type = 27
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!6B", *self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = internal_mac()
+        _type = reader.read("!H")[0]
+        assert(_type == 27)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("internal_mac {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[27] = internal_mac
+
+class interval(bsn_tlv):
+    type = 58
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = interval()
+        _type = reader.read("!H")[0]
+        assert(_type == 58)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("interval {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[58] = interval
+
+class ip_proto(bsn_tlv):
+    type = 67
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!B", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ip_proto()
+        _type = reader.read("!H")[0]
+        assert(_type == 67)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ip_proto {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[67] = ip_proto
+
+class ipv4(bsn_tlv):
+    type = 4
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv4()
+        _type = reader.read("!H")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv4 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[4] = ipv4
+
+class ipv4_dst(bsn_tlv):
+    type = 35
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv4_dst()
+        _type = reader.read("!H")[0]
+        assert(_type == 35)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv4_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[35] = ipv4_dst
+
+class ipv4_netmask(bsn_tlv):
+    type = 60
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv4_netmask()
+        _type = reader.read("!H")[0]
+        assert(_type == 60)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv4_netmask {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[60] = ipv4_netmask
+
+class ipv4_src(bsn_tlv):
+    type = 34
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv4_src()
+        _type = reader.read("!H")[0]
+        assert(_type == 34)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv4_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[34] = ipv4_src
+
+class l2_multicast_lookup(bsn_tlv):
+    type = 79
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = l2_multicast_lookup()
+        _type = reader.read("!H")[0]
+        assert(_type == 79)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("l2_multicast_lookup {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[79] = l2_multicast_lookup
+
+class mac(bsn_tlv):
+    type = 1
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!6B", *self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = mac()
+        _type = reader.read("!H")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("mac {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[1] = mac
+
+class mac_mask(bsn_tlv):
+    type = 56
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!6B", *self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = mac_mask()
+        _type = reader.read("!H")[0]
+        assert(_type == 56)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("mac_mask {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[56] = mac_mask
+
+class miss_packets(bsn_tlv):
+    type = 13
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!Q", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = miss_packets()
+        _type = reader.read("!H")[0]
+        assert(_type == 13)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("miss_packets {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[13] = miss_packets
+
+class mpls_control_word(bsn_tlv):
+    type = 62
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!B", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = mpls_control_word()
+        _type = reader.read("!H")[0]
+        assert(_type == 62)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("mpls_control_word {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[62] = mpls_control_word
+
+class mpls_label(bsn_tlv):
+    type = 61
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = mpls_label()
+        _type = reader.read("!H")[0]
+        assert(_type == 61)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("mpls_label {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[61] = mpls_label
+
+class mpls_sequenced(bsn_tlv):
+    type = 63
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!B", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = mpls_sequenced()
+        _type = reader.read("!H")[0]
+        assert(_type == 63)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("mpls_sequenced {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[63] = mpls_sequenced
+
+class name(bsn_tlv):
+    type = 52
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(self.value)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = name()
+        _type = reader.read("!H")[0]
+        assert(_type == 52)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("name {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[52] = name
+
+class offset(bsn_tlv):
+    type = 82
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = offset()
+        _type = reader.read("!H")[0]
+        assert(_type == 82)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("offset {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[82] = offset
+
+class partner_key(bsn_tlv):
+    type = 51
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = partner_key()
+        _type = reader.read("!H")[0]
+        assert(_type == 51)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("partner_key {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[51] = partner_key
+
+class partner_port_num(bsn_tlv):
+    type = 50
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = partner_port_num()
+        _type = reader.read("!H")[0]
+        assert(_type == 50)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("partner_port_num {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[50] = partner_port_num
+
+class partner_port_priority(bsn_tlv):
+    type = 49
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = partner_port_priority()
+        _type = reader.read("!H")[0]
+        assert(_type == 49)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("partner_port_priority {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[49] = partner_port_priority
+
+class partner_state(bsn_tlv):
+    type = 54
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!B", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = partner_state()
+        _type = reader.read("!H")[0]
+        assert(_type == 54)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("partner_state {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[54] = partner_state
+
+class partner_system_mac(bsn_tlv):
+    type = 48
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!6B", *self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = partner_system_mac()
+        _type = reader.read("!H")[0]
+        assert(_type == 48)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("partner_system_mac {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[48] = partner_system_mac
+
+class partner_system_priority(bsn_tlv):
+    type = 47
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = partner_system_priority()
+        _type = reader.read("!H")[0]
+        assert(_type == 47)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("partner_system_priority {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[47] = partner_system_priority
+
+class port(bsn_tlv):
+    type = 0
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(util.pack_port_no(self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port()
+        _type = reader.read("!H")[0]
+        assert(_type == 0)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = util.unpack_port_no(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_port(self.value))
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[0] = port
+
+class priority(bsn_tlv):
+    type = 57
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = priority()
+        _type = reader.read("!H")[0]
+        assert(_type == 57)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("priority {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[57] = priority
+
+class queue_id(bsn_tlv):
+    type = 20
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_id()
+        _type = reader.read("!H")[0]
+        assert(_type == 20)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[20] = queue_id
+
+class queue_weight(bsn_tlv):
+    type = 21
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_weight()
+        _type = reader.read("!H")[0]
+        assert(_type == 21)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_weight {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[21] = queue_weight
+
+class reference(bsn_tlv):
+    type = 59
+
+    def __init__(self, table_id=None, key=None):
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if key != None:
+            self.key = key
+        else:
+            self.key = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.table_id))
+        packed.append(loxi.generic_util.pack_list(self.key))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = reference()
+        _type = reader.read("!H")[0]
+        assert(_type == 59)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.table_id = reader.read("!H")[0]
+        obj.key = loxi.generic_util.unpack_list(reader, ofp.bsn_tlv.bsn_tlv.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.table_id != other.table_id: return False
+        if self.key != other.key: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("reference {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("key = ");
+                q.pp(self.key)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[59] = reference
+
+class reply_packets(bsn_tlv):
+    type = 12
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!Q", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = reply_packets()
+        _type = reader.read("!H")[0]
+        assert(_type == 12)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("reply_packets {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[12] = reply_packets
+
+class request_packets(bsn_tlv):
+    type = 11
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!Q", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = request_packets()
+        _type = reader.read("!H")[0]
+        assert(_type == 11)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("request_packets {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[11] = request_packets
+
+class rx_bytes(bsn_tlv):
+    type = 71
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!Q", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = rx_bytes()
+        _type = reader.read("!H")[0]
+        assert(_type == 71)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("rx_bytes {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[71] = rx_bytes
+
+class rx_packets(bsn_tlv):
+    type = 2
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!Q", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = rx_packets()
+        _type = reader.read("!H")[0]
+        assert(_type == 2)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("rx_packets {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[2] = rx_packets
+
+class sampling_rate(bsn_tlv):
+    type = 30
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = sampling_rate()
+        _type = reader.read("!H")[0]
+        assert(_type == 30)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("sampling_rate {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[30] = sampling_rate
+
+class set_loopback_mode(bsn_tlv):
+    type = 74
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_loopback_mode()
+        _type = reader.read("!H")[0]
+        assert(_type == 74)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_loopback_mode {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[74] = set_loopback_mode
+
+class strip_mpls_l2_on_ingress(bsn_tlv):
+    type = 75
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = strip_mpls_l2_on_ingress()
+        _type = reader.read("!H")[0]
+        assert(_type == 75)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("strip_mpls_l2_on_ingress {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[75] = strip_mpls_l2_on_ingress
+
+class strip_mpls_l3_on_ingress(bsn_tlv):
+    type = 76
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = strip_mpls_l3_on_ingress()
+        _type = reader.read("!H")[0]
+        assert(_type == 76)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("strip_mpls_l3_on_ingress {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[76] = strip_mpls_l3_on_ingress
+
+class strip_vlan_on_egress(bsn_tlv):
+    type = 73
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = strip_vlan_on_egress()
+        _type = reader.read("!H")[0]
+        assert(_type == 73)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("strip_vlan_on_egress {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[73] = strip_vlan_on_egress
+
+class sub_agent_id(bsn_tlv):
+    type = 38
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = sub_agent_id()
+        _type = reader.read("!H")[0]
+        assert(_type == 38)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("sub_agent_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[38] = sub_agent_id
+
+class tcp_dst(bsn_tlv):
+    type = 66
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = tcp_dst()
+        _type = reader.read("!H")[0]
+        assert(_type == 66)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("tcp_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[66] = tcp_dst
+
+class tcp_src(bsn_tlv):
+    type = 65
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = tcp_src()
+        _type = reader.read("!H")[0]
+        assert(_type == 65)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("tcp_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[65] = tcp_src
+
+class tx_bytes(bsn_tlv):
+    type = 39
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!Q", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = tx_bytes()
+        _type = reader.read("!H")[0]
+        assert(_type == 39)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("tx_bytes {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[39] = tx_bytes
+
+class tx_packets(bsn_tlv):
+    type = 3
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!Q", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = tx_packets()
+        _type = reader.read("!H")[0]
+        assert(_type == 3)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("tx_packets {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[3] = tx_packets
+
+class udf_anchor(bsn_tlv):
+    type = 16
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = udf_anchor()
+        _type = reader.read("!H")[0]
+        assert(_type == 16)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("udf_anchor {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[16] = udf_anchor
+
+class udf_id(bsn_tlv):
+    type = 15
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = udf_id()
+        _type = reader.read("!H")[0]
+        assert(_type == 15)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("udf_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[15] = udf_id
+
+class udf_length(bsn_tlv):
+    type = 18
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = udf_length()
+        _type = reader.read("!H")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("udf_length {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[18] = udf_length
+
+class udf_offset(bsn_tlv):
+    type = 17
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = udf_offset()
+        _type = reader.read("!H")[0]
+        assert(_type == 17)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("udf_offset {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[17] = udf_offset
+
+class udp_dst(bsn_tlv):
+    type = 37
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = udp_dst()
+        _type = reader.read("!H")[0]
+        assert(_type == 37)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("udp_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[37] = udp_dst
+
+class udp_src(bsn_tlv):
+    type = 36
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = udp_src()
+        _type = reader.read("!H")[0]
+        assert(_type == 36)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("udp_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[36] = udp_src
+
+class unicast_query_timeout(bsn_tlv):
+    type = 9
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = unicast_query_timeout()
+        _type = reader.read("!H")[0]
+        assert(_type == 9)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("unicast_query_timeout {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[9] = unicast_query_timeout
+
+class vlan_pcp(bsn_tlv):
+    type = 72
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!B", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = vlan_pcp()
+        _type = reader.read("!H")[0]
+        assert(_type == 72)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("vlan_pcp {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[72] = vlan_pcp
+
+class vlan_vid(bsn_tlv):
+    type = 6
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = vlan_vid()
+        _type = reader.read("!H")[0]
+        assert(_type == 6)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("vlan_vid {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[6] = vlan_vid
+
+class vlan_vid_mask(bsn_tlv):
+    type = 77
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = vlan_vid_mask()
+        _type = reader.read("!H")[0]
+        assert(_type == 77)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("vlan_vid_mask {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[77] = vlan_vid_mask
+
+class vrf(bsn_tlv):
+    type = 19
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = vrf()
+        _type = reader.read("!H")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("vrf {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_tlv.subtypes[19] = vrf
+
+
diff --git a/Fabric/Utilities/src/python/loxi/of14/bundle_prop.py b/Fabric/Utilities/src/python/loxi/of14/bundle_prop.py
new file mode 100644
index 0000000..61ad92f
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of14/bundle_prop.py
@@ -0,0 +1,141 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of14']
+
+class bundle_prop(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = bundle_prop.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = bundle_prop()
+        obj.type = reader.read("!H")[0]
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bundle_prop {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class experimenter(bundle_prop):
+    subtypes = {}
+
+    type = 65535
+
+    def __init__(self, experimenter=None, exp_type=None):
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if exp_type != None:
+            self.exp_type = exp_type
+        else:
+            self.exp_type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.exp_type))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 4)
+        subclass = experimenter.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = experimenter()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.experimenter = reader.read("!L")[0]
+        obj.exp_type = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.experimenter != other.experimenter: return False
+        if self.exp_type != other.exp_type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("exp_type = ");
+                q.text("%#x" % self.exp_type)
+            q.breakable()
+        q.text('}')
+
+bundle_prop.subtypes[65535] = experimenter
+
+
diff --git a/Fabric/Utilities/src/python/loxi/of14/common.py b/Fabric/Utilities/src/python/loxi/of14/common.py
new file mode 100644
index 0000000..76098fc
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of14/common.py
@@ -0,0 +1,4333 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of14']
+
+class bsn_controller_connection(loxi.OFObject):
+
+    def __init__(self, state=None, auxiliary_id=None, role=None, uri=None):
+        if state != None:
+            self.state = state
+        else:
+            self.state = 0
+        if auxiliary_id != None:
+            self.auxiliary_id = auxiliary_id
+        else:
+            self.auxiliary_id = 0
+        if role != None:
+            self.role = role
+        else:
+            self.role = 0
+        if uri != None:
+            self.uri = uri
+        else:
+            self.uri = ""
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.state))
+        packed.append(struct.pack("!B", self.auxiliary_id))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!L", self.role))
+        packed.append(struct.pack("!256s", self.uri))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_controller_connection()
+        obj.state = reader.read("!B")[0]
+        obj.auxiliary_id = reader.read("!B")[0]
+        reader.skip(2)
+        obj.role = reader.read("!L")[0]
+        obj.uri = reader.read("!256s")[0].rstrip("\x00")
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.state != other.state: return False
+        if self.auxiliary_id != other.auxiliary_id: return False
+        if self.role != other.role: return False
+        if self.uri != other.uri: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_controller_connection {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("state = ");
+                q.text("%#x" % self.state)
+                q.text(","); q.breakable()
+                q.text("auxiliary_id = ");
+                q.text("%#x" % self.auxiliary_id)
+                q.text(","); q.breakable()
+                q.text("role = ");
+                q.text("%#x" % self.role)
+                q.text(","); q.breakable()
+                q.text("uri = ");
+                q.pp(self.uri)
+            q.breakable()
+        q.text('}')
+
+
+class bsn_debug_counter_desc_stats_entry(loxi.OFObject):
+
+    def __init__(self, counter_id=None, name=None, description=None):
+        if counter_id != None:
+            self.counter_id = counter_id
+        else:
+            self.counter_id = 0
+        if name != None:
+            self.name = name
+        else:
+            self.name = ""
+        if description != None:
+            self.description = description
+        else:
+            self.description = ""
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!Q", self.counter_id))
+        packed.append(struct.pack("!64s", self.name))
+        packed.append(struct.pack("!256s", self.description))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_debug_counter_desc_stats_entry()
+        obj.counter_id = reader.read("!Q")[0]
+        obj.name = reader.read("!64s")[0].rstrip("\x00")
+        obj.description = reader.read("!256s")[0].rstrip("\x00")
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.counter_id != other.counter_id: return False
+        if self.name != other.name: return False
+        if self.description != other.description: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_debug_counter_desc_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("counter_id = ");
+                q.text("%#x" % self.counter_id)
+                q.text(","); q.breakable()
+                q.text("name = ");
+                q.pp(self.name)
+                q.text(","); q.breakable()
+                q.text("description = ");
+                q.pp(self.description)
+            q.breakable()
+        q.text('}')
+
+
+class bsn_debug_counter_stats_entry(loxi.OFObject):
+
+    def __init__(self, counter_id=None, value=None):
+        if counter_id != None:
+            self.counter_id = counter_id
+        else:
+            self.counter_id = 0
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!Q", self.counter_id))
+        packed.append(struct.pack("!Q", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_debug_counter_stats_entry()
+        obj.counter_id = reader.read("!Q")[0]
+        obj.value = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.counter_id != other.counter_id: return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_debug_counter_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("counter_id = ");
+                q.text("%#x" % self.counter_id)
+                q.text(","); q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+
+class bsn_flow_checksum_bucket_stats_entry(loxi.OFObject):
+
+    def __init__(self, checksum=None):
+        if checksum != None:
+            self.checksum = checksum
+        else:
+            self.checksum = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!Q", self.checksum))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_flow_checksum_bucket_stats_entry()
+        obj.checksum = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.checksum != other.checksum: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_flow_checksum_bucket_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("checksum = ");
+                q.text("%#x" % self.checksum)
+            q.breakable()
+        q.text('}')
+
+
+class bsn_generic_stats_entry(loxi.OFObject):
+
+    def __init__(self, tlvs=None):
+        if tlvs != None:
+            self.tlvs = tlvs
+        else:
+            self.tlvs = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 0
+        packed.append(loxi.generic_util.pack_list(self.tlvs))
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_generic_stats_entry()
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 2)
+        obj.tlvs = loxi.generic_util.unpack_list(reader, ofp.bsn_tlv.bsn_tlv.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.tlvs != other.tlvs: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_generic_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("tlvs = ");
+                q.pp(self.tlvs)
+            q.breakable()
+        q.text('}')
+
+
+class bsn_gentable_bucket_stats_entry(loxi.OFObject):
+
+    def __init__(self, checksum=None):
+        if checksum != None:
+            self.checksum = checksum
+        else:
+            self.checksum = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(util.pack_checksum_128(self.checksum))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_bucket_stats_entry()
+        obj.checksum = util.unpack_checksum_128(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.checksum != other.checksum: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_bucket_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("checksum = ");
+                q.pp(self.checksum)
+            q.breakable()
+        q.text('}')
+
+
+class bsn_gentable_desc_stats_entry(loxi.OFObject):
+
+    def __init__(self, table_id=None, name=None, buckets_size=None, max_entries=None):
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if name != None:
+            self.name = name
+        else:
+            self.name = ""
+        if buckets_size != None:
+            self.buckets_size = buckets_size
+        else:
+            self.buckets_size = 0
+        if max_entries != None:
+            self.max_entries = max_entries
+        else:
+            self.max_entries = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 0
+        packed.append(struct.pack("!H", self.table_id))
+        packed.append(struct.pack("!32s", self.name))
+        packed.append(struct.pack("!L", self.buckets_size))
+        packed.append(struct.pack("!L", self.max_entries))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_desc_stats_entry()
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 2)
+        obj.table_id = reader.read("!H")[0]
+        obj.name = reader.read("!32s")[0].rstrip("\x00")
+        obj.buckets_size = reader.read("!L")[0]
+        obj.max_entries = reader.read("!L")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.table_id != other.table_id: return False
+        if self.name != other.name: return False
+        if self.buckets_size != other.buckets_size: return False
+        if self.max_entries != other.max_entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_desc_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("name = ");
+                q.pp(self.name)
+                q.text(","); q.breakable()
+                q.text("buckets_size = ");
+                q.text("%#x" % self.buckets_size)
+                q.text(","); q.breakable()
+                q.text("max_entries = ");
+                q.text("%#x" % self.max_entries)
+            q.breakable()
+        q.text('}')
+
+
+class bsn_gentable_entry_desc_stats_entry(loxi.OFObject):
+
+    def __init__(self, checksum=None, key=None, value=None):
+        if checksum != None:
+            self.checksum = checksum
+        else:
+            self.checksum = 0
+        if key != None:
+            self.key = key
+        else:
+            self.key = []
+        if value != None:
+            self.value = value
+        else:
+            self.value = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 0
+        packed.append(struct.pack("!H", 0)) # placeholder for key_length at index 1
+        packed.append(util.pack_checksum_128(self.checksum))
+        packed.append(loxi.generic_util.pack_list(self.key))
+        packed[1] = struct.pack("!H", len(packed[-1]))
+        packed.append(loxi.generic_util.pack_list(self.value))
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_entry_desc_stats_entry()
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 2)
+        _key_length = reader.read("!H")[0]
+        obj.checksum = util.unpack_checksum_128(reader)
+        obj.key = loxi.generic_util.unpack_list(reader.slice(_key_length), ofp.bsn_tlv.bsn_tlv.unpack)
+        obj.value = loxi.generic_util.unpack_list(reader, ofp.bsn_tlv.bsn_tlv.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.checksum != other.checksum: return False
+        if self.key != other.key: return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_entry_desc_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("checksum = ");
+                q.pp(self.checksum)
+                q.text(","); q.breakable()
+                q.text("key = ");
+                q.pp(self.key)
+                q.text(","); q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+            q.breakable()
+        q.text('}')
+
+
+class bsn_gentable_entry_stats_entry(loxi.OFObject):
+
+    def __init__(self, key=None, stats=None):
+        if key != None:
+            self.key = key
+        else:
+            self.key = []
+        if stats != None:
+            self.stats = stats
+        else:
+            self.stats = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 0
+        packed.append(struct.pack("!H", 0)) # placeholder for key_length at index 1
+        packed.append(loxi.generic_util.pack_list(self.key))
+        packed[1] = struct.pack("!H", len(packed[-1]))
+        packed.append(loxi.generic_util.pack_list(self.stats))
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_entry_stats_entry()
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 2)
+        _key_length = reader.read("!H")[0]
+        obj.key = loxi.generic_util.unpack_list(reader.slice(_key_length), ofp.bsn_tlv.bsn_tlv.unpack)
+        obj.stats = loxi.generic_util.unpack_list(reader, ofp.bsn_tlv.bsn_tlv.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.key != other.key: return False
+        if self.stats != other.stats: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_entry_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("key = ");
+                q.pp(self.key)
+                q.text(","); q.breakable()
+                q.text("stats = ");
+                q.pp(self.stats)
+            q.breakable()
+        q.text('}')
+
+
+class bsn_gentable_stats_entry(loxi.OFObject):
+
+    def __init__(self, table_id=None, entry_count=None, checksum=None):
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if entry_count != None:
+            self.entry_count = entry_count
+        else:
+            self.entry_count = 0
+        if checksum != None:
+            self.checksum = checksum
+        else:
+            self.checksum = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.table_id))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!L", self.entry_count))
+        packed.append(util.pack_checksum_128(self.checksum))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_stats_entry()
+        obj.table_id = reader.read("!H")[0]
+        reader.skip(2)
+        obj.entry_count = reader.read("!L")[0]
+        obj.checksum = util.unpack_checksum_128(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.table_id != other.table_id: return False
+        if self.entry_count != other.entry_count: return False
+        if self.checksum != other.checksum: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("entry_count = ");
+                q.text("%#x" % self.entry_count)
+                q.text(","); q.breakable()
+                q.text("checksum = ");
+                q.pp(self.checksum)
+            q.breakable()
+        q.text('}')
+
+
+class bsn_interface(loxi.OFObject):
+
+    def __init__(self, hw_addr=None, name=None, ipv4_addr=None, ipv4_netmask=None):
+        if hw_addr != None:
+            self.hw_addr = hw_addr
+        else:
+            self.hw_addr = [0,0,0,0,0,0]
+        if name != None:
+            self.name = name
+        else:
+            self.name = ""
+        if ipv4_addr != None:
+            self.ipv4_addr = ipv4_addr
+        else:
+            self.ipv4_addr = 0
+        if ipv4_netmask != None:
+            self.ipv4_netmask = ipv4_netmask
+        else:
+            self.ipv4_netmask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!6B", *self.hw_addr))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!16s", self.name))
+        packed.append(struct.pack("!L", self.ipv4_addr))
+        packed.append(struct.pack("!L", self.ipv4_netmask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_interface()
+        obj.hw_addr = list(reader.read('!6B'))
+        reader.skip(2)
+        obj.name = reader.read("!16s")[0].rstrip("\x00")
+        obj.ipv4_addr = reader.read("!L")[0]
+        obj.ipv4_netmask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.hw_addr != other.hw_addr: return False
+        if self.name != other.name: return False
+        if self.ipv4_addr != other.ipv4_addr: return False
+        if self.ipv4_netmask != other.ipv4_netmask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_interface {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("hw_addr = ");
+                q.text(util.pretty_mac(self.hw_addr))
+                q.text(","); q.breakable()
+                q.text("name = ");
+                q.pp(self.name)
+                q.text(","); q.breakable()
+                q.text("ipv4_addr = ");
+                q.text(util.pretty_ipv4(self.ipv4_addr))
+                q.text(","); q.breakable()
+                q.text("ipv4_netmask = ");
+                q.text(util.pretty_ipv4(self.ipv4_netmask))
+            q.breakable()
+        q.text('}')
+
+
+class bsn_lacp_stats_entry(loxi.OFObject):
+
+    def __init__(self, port_no=None, actor_sys_priority=None, actor_sys_mac=None, actor_port_priority=None, actor_port_num=None, actor_key=None, convergence_status=None, partner_sys_priority=None, partner_sys_mac=None, partner_port_priority=None, partner_port_num=None, partner_key=None):
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if actor_sys_priority != None:
+            self.actor_sys_priority = actor_sys_priority
+        else:
+            self.actor_sys_priority = 0
+        if actor_sys_mac != None:
+            self.actor_sys_mac = actor_sys_mac
+        else:
+            self.actor_sys_mac = [0,0,0,0,0,0]
+        if actor_port_priority != None:
+            self.actor_port_priority = actor_port_priority
+        else:
+            self.actor_port_priority = 0
+        if actor_port_num != None:
+            self.actor_port_num = actor_port_num
+        else:
+            self.actor_port_num = 0
+        if actor_key != None:
+            self.actor_key = actor_key
+        else:
+            self.actor_key = 0
+        if convergence_status != None:
+            self.convergence_status = convergence_status
+        else:
+            self.convergence_status = 0
+        if partner_sys_priority != None:
+            self.partner_sys_priority = partner_sys_priority
+        else:
+            self.partner_sys_priority = 0
+        if partner_sys_mac != None:
+            self.partner_sys_mac = partner_sys_mac
+        else:
+            self.partner_sys_mac = [0,0,0,0,0,0]
+        if partner_port_priority != None:
+            self.partner_port_priority = partner_port_priority
+        else:
+            self.partner_port_priority = 0
+        if partner_port_num != None:
+            self.partner_port_num = partner_port_num
+        else:
+            self.partner_port_num = 0
+        if partner_key != None:
+            self.partner_key = partner_key
+        else:
+            self.partner_key = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!H", self.actor_sys_priority))
+        packed.append(struct.pack("!6B", *self.actor_sys_mac))
+        packed.append(struct.pack("!H", self.actor_port_priority))
+        packed.append(struct.pack("!H", self.actor_port_num))
+        packed.append(struct.pack("!H", self.actor_key))
+        packed.append(struct.pack("!B", self.convergence_status))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!H", self.partner_sys_priority))
+        packed.append(struct.pack("!6B", *self.partner_sys_mac))
+        packed.append(struct.pack("!H", self.partner_port_priority))
+        packed.append(struct.pack("!H", self.partner_port_num))
+        packed.append(struct.pack("!H", self.partner_key))
+        packed.append('\x00' * 2)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_lacp_stats_entry()
+        obj.port_no = util.unpack_port_no(reader)
+        obj.actor_sys_priority = reader.read("!H")[0]
+        obj.actor_sys_mac = list(reader.read('!6B'))
+        obj.actor_port_priority = reader.read("!H")[0]
+        obj.actor_port_num = reader.read("!H")[0]
+        obj.actor_key = reader.read("!H")[0]
+        obj.convergence_status = reader.read("!B")[0]
+        reader.skip(1)
+        obj.partner_sys_priority = reader.read("!H")[0]
+        obj.partner_sys_mac = list(reader.read('!6B'))
+        obj.partner_port_priority = reader.read("!H")[0]
+        obj.partner_port_num = reader.read("!H")[0]
+        obj.partner_key = reader.read("!H")[0]
+        reader.skip(2)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.port_no != other.port_no: return False
+        if self.actor_sys_priority != other.actor_sys_priority: return False
+        if self.actor_sys_mac != other.actor_sys_mac: return False
+        if self.actor_port_priority != other.actor_port_priority: return False
+        if self.actor_port_num != other.actor_port_num: return False
+        if self.actor_key != other.actor_key: return False
+        if self.convergence_status != other.convergence_status: return False
+        if self.partner_sys_priority != other.partner_sys_priority: return False
+        if self.partner_sys_mac != other.partner_sys_mac: return False
+        if self.partner_port_priority != other.partner_port_priority: return False
+        if self.partner_port_num != other.partner_port_num: return False
+        if self.partner_key != other.partner_key: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_lacp_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("actor_sys_priority = ");
+                q.text("%#x" % self.actor_sys_priority)
+                q.text(","); q.breakable()
+                q.text("actor_sys_mac = ");
+                q.text(util.pretty_mac(self.actor_sys_mac))
+                q.text(","); q.breakable()
+                q.text("actor_port_priority = ");
+                q.text("%#x" % self.actor_port_priority)
+                q.text(","); q.breakable()
+                q.text("actor_port_num = ");
+                q.text("%#x" % self.actor_port_num)
+                q.text(","); q.breakable()
+                q.text("actor_key = ");
+                q.text("%#x" % self.actor_key)
+                q.text(","); q.breakable()
+                q.text("convergence_status = ");
+                q.text("%#x" % self.convergence_status)
+                q.text(","); q.breakable()
+                q.text("partner_sys_priority = ");
+                q.text("%#x" % self.partner_sys_priority)
+                q.text(","); q.breakable()
+                q.text("partner_sys_mac = ");
+                q.text(util.pretty_mac(self.partner_sys_mac))
+                q.text(","); q.breakable()
+                q.text("partner_port_priority = ");
+                q.text("%#x" % self.partner_port_priority)
+                q.text(","); q.breakable()
+                q.text("partner_port_num = ");
+                q.text("%#x" % self.partner_port_num)
+                q.text(","); q.breakable()
+                q.text("partner_key = ");
+                q.text("%#x" % self.partner_key)
+            q.breakable()
+        q.text('}')
+
+
+class bsn_port_counter_stats_entry(loxi.OFObject):
+
+    def __init__(self, port_no=None, values=None):
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if values != None:
+            self.values = values
+        else:
+            self.values = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 0
+        packed.append('\x00' * 2)
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(loxi.generic_util.pack_list(self.values))
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_port_counter_stats_entry()
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 2)
+        reader.skip(2)
+        obj.port_no = util.unpack_port_no(reader)
+        obj.values = loxi.generic_util.unpack_list(reader, ofp.common.uint64.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.port_no != other.port_no: return False
+        if self.values != other.values: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_port_counter_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("values = ");
+                q.pp(self.values)
+            q.breakable()
+        q.text('}')
+
+
+class bsn_switch_pipeline_stats_entry(loxi.OFObject):
+
+    def __init__(self, pipeline=None):
+        if pipeline != None:
+            self.pipeline = pipeline
+        else:
+            self.pipeline = ""
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!256s", self.pipeline))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_switch_pipeline_stats_entry()
+        obj.pipeline = reader.read("!256s")[0].rstrip("\x00")
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.pipeline != other.pipeline: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_switch_pipeline_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("pipeline = ");
+                q.pp(self.pipeline)
+            q.breakable()
+        q.text('}')
+
+
+class bsn_table_checksum_stats_entry(loxi.OFObject):
+
+    def __init__(self, table_id=None, checksum=None):
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if checksum != None:
+            self.checksum = checksum
+        else:
+            self.checksum = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append(struct.pack("!Q", self.checksum))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_table_checksum_stats_entry()
+        obj.table_id = reader.read("!B")[0]
+        obj.checksum = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.table_id != other.table_id: return False
+        if self.checksum != other.checksum: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_table_checksum_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("checksum = ");
+                q.text("%#x" % self.checksum)
+            q.breakable()
+        q.text('}')
+
+
+class bsn_vport(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = bsn_vport.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = bsn_vport()
+        obj.type = reader.read("!H")[0]
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vport {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class bsn_vlan_counter_stats_entry(loxi.OFObject):
+
+    def __init__(self, vlan_vid=None, values=None):
+        if vlan_vid != None:
+            self.vlan_vid = vlan_vid
+        else:
+            self.vlan_vid = 0
+        if values != None:
+            self.values = values
+        else:
+            self.values = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 0
+        packed.append(struct.pack("!H", self.vlan_vid))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.values))
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vlan_counter_stats_entry()
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 2)
+        obj.vlan_vid = reader.read("!H")[0]
+        reader.skip(4)
+        obj.values = loxi.generic_util.unpack_list(reader, ofp.common.uint64.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.vlan_vid != other.vlan_vid: return False
+        if self.values != other.values: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vlan_counter_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("vlan_vid = ");
+                q.text("%#x" % self.vlan_vid)
+                q.text(","); q.breakable()
+                q.text("values = ");
+                q.pp(self.values)
+            q.breakable()
+        q.text('}')
+
+
+class bsn_vport_l2gre(bsn_vport):
+    type = 1
+
+    def __init__(self, flags=None, port_no=None, loopback_port_no=None, local_mac=None, nh_mac=None, src_ip=None, dst_ip=None, dscp=None, ttl=None, vpn=None, rate_limit=None, if_name=None):
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if loopback_port_no != None:
+            self.loopback_port_no = loopback_port_no
+        else:
+            self.loopback_port_no = 0
+        if local_mac != None:
+            self.local_mac = local_mac
+        else:
+            self.local_mac = [0,0,0,0,0,0]
+        if nh_mac != None:
+            self.nh_mac = nh_mac
+        else:
+            self.nh_mac = [0,0,0,0,0,0]
+        if src_ip != None:
+            self.src_ip = src_ip
+        else:
+            self.src_ip = 0
+        if dst_ip != None:
+            self.dst_ip = dst_ip
+        else:
+            self.dst_ip = 0
+        if dscp != None:
+            self.dscp = dscp
+        else:
+            self.dscp = 0
+        if ttl != None:
+            self.ttl = ttl
+        else:
+            self.ttl = 0
+        if vpn != None:
+            self.vpn = vpn
+        else:
+            self.vpn = 0
+        if rate_limit != None:
+            self.rate_limit = rate_limit
+        else:
+            self.rate_limit = 0
+        if if_name != None:
+            self.if_name = if_name
+        else:
+            self.if_name = ""
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.flags))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(util.pack_port_no(self.loopback_port_no))
+        packed.append(struct.pack("!6B", *self.local_mac))
+        packed.append(struct.pack("!6B", *self.nh_mac))
+        packed.append(struct.pack("!L", self.src_ip))
+        packed.append(struct.pack("!L", self.dst_ip))
+        packed.append(struct.pack("!B", self.dscp))
+        packed.append(struct.pack("!B", self.ttl))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!L", self.vpn))
+        packed.append(struct.pack("!L", self.rate_limit))
+        packed.append(struct.pack("!16s", self.if_name))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vport_l2gre()
+        _type = reader.read("!H")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.flags = reader.read("!L")[0]
+        obj.port_no = util.unpack_port_no(reader)
+        obj.loopback_port_no = util.unpack_port_no(reader)
+        obj.local_mac = list(reader.read('!6B'))
+        obj.nh_mac = list(reader.read('!6B'))
+        obj.src_ip = reader.read("!L")[0]
+        obj.dst_ip = reader.read("!L")[0]
+        obj.dscp = reader.read("!B")[0]
+        obj.ttl = reader.read("!B")[0]
+        reader.skip(2)
+        obj.vpn = reader.read("!L")[0]
+        obj.rate_limit = reader.read("!L")[0]
+        obj.if_name = reader.read("!16s")[0].rstrip("\x00")
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.flags != other.flags: return False
+        if self.port_no != other.port_no: return False
+        if self.loopback_port_no != other.loopback_port_no: return False
+        if self.local_mac != other.local_mac: return False
+        if self.nh_mac != other.nh_mac: return False
+        if self.src_ip != other.src_ip: return False
+        if self.dst_ip != other.dst_ip: return False
+        if self.dscp != other.dscp: return False
+        if self.ttl != other.ttl: return False
+        if self.vpn != other.vpn: return False
+        if self.rate_limit != other.rate_limit: return False
+        if self.if_name != other.if_name: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vport_l2gre {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("loopback_port_no = ");
+                q.text(util.pretty_port(self.loopback_port_no))
+                q.text(","); q.breakable()
+                q.text("local_mac = ");
+                q.text(util.pretty_mac(self.local_mac))
+                q.text(","); q.breakable()
+                q.text("nh_mac = ");
+                q.text(util.pretty_mac(self.nh_mac))
+                q.text(","); q.breakable()
+                q.text("src_ip = ");
+                q.text(util.pretty_ipv4(self.src_ip))
+                q.text(","); q.breakable()
+                q.text("dst_ip = ");
+                q.text(util.pretty_ipv4(self.dst_ip))
+                q.text(","); q.breakable()
+                q.text("dscp = ");
+                q.text("%#x" % self.dscp)
+                q.text(","); q.breakable()
+                q.text("ttl = ");
+                q.text("%#x" % self.ttl)
+                q.text(","); q.breakable()
+                q.text("vpn = ");
+                q.text("%#x" % self.vpn)
+                q.text(","); q.breakable()
+                q.text("rate_limit = ");
+                q.text("%#x" % self.rate_limit)
+                q.text(","); q.breakable()
+                q.text("if_name = ");
+                q.pp(self.if_name)
+            q.breakable()
+        q.text('}')
+
+bsn_vport.subtypes[1] = bsn_vport_l2gre
+
+class bsn_vport_q_in_q(bsn_vport):
+    type = 0
+
+    def __init__(self, port_no=None, ingress_tpid=None, ingress_vlan_id=None, egress_tpid=None, egress_vlan_id=None, if_name=None):
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if ingress_tpid != None:
+            self.ingress_tpid = ingress_tpid
+        else:
+            self.ingress_tpid = 0
+        if ingress_vlan_id != None:
+            self.ingress_vlan_id = ingress_vlan_id
+        else:
+            self.ingress_vlan_id = 0
+        if egress_tpid != None:
+            self.egress_tpid = egress_tpid
+        else:
+            self.egress_tpid = 0
+        if egress_vlan_id != None:
+            self.egress_vlan_id = egress_vlan_id
+        else:
+            self.egress_vlan_id = 0
+        if if_name != None:
+            self.if_name = if_name
+        else:
+            self.if_name = ""
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.port_no))
+        packed.append(struct.pack("!H", self.ingress_tpid))
+        packed.append(struct.pack("!H", self.ingress_vlan_id))
+        packed.append(struct.pack("!H", self.egress_tpid))
+        packed.append(struct.pack("!H", self.egress_vlan_id))
+        packed.append(struct.pack("!16s", self.if_name))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vport_q_in_q()
+        _type = reader.read("!H")[0]
+        assert(_type == 0)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.port_no = reader.read("!L")[0]
+        obj.ingress_tpid = reader.read("!H")[0]
+        obj.ingress_vlan_id = reader.read("!H")[0]
+        obj.egress_tpid = reader.read("!H")[0]
+        obj.egress_vlan_id = reader.read("!H")[0]
+        obj.if_name = reader.read("!16s")[0].rstrip("\x00")
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.port_no != other.port_no: return False
+        if self.ingress_tpid != other.ingress_tpid: return False
+        if self.ingress_vlan_id != other.ingress_vlan_id: return False
+        if self.egress_tpid != other.egress_tpid: return False
+        if self.egress_vlan_id != other.egress_vlan_id: return False
+        if self.if_name != other.if_name: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vport_q_in_q {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("port_no = ");
+                q.text("%#x" % self.port_no)
+                q.text(","); q.breakable()
+                q.text("ingress_tpid = ");
+                q.text("%#x" % self.ingress_tpid)
+                q.text(","); q.breakable()
+                q.text("ingress_vlan_id = ");
+                q.text("%#x" % self.ingress_vlan_id)
+                q.text(","); q.breakable()
+                q.text("egress_tpid = ");
+                q.text("%#x" % self.egress_tpid)
+                q.text(","); q.breakable()
+                q.text("egress_vlan_id = ");
+                q.text("%#x" % self.egress_vlan_id)
+                q.text(","); q.breakable()
+                q.text("if_name = ");
+                q.pp(self.if_name)
+            q.breakable()
+        q.text('}')
+
+bsn_vport.subtypes[0] = bsn_vport_q_in_q
+
+class bsn_vrf_counter_stats_entry(loxi.OFObject):
+
+    def __init__(self, vrf=None, values=None):
+        if vrf != None:
+            self.vrf = vrf
+        else:
+            self.vrf = 0
+        if values != None:
+            self.values = values
+        else:
+            self.values = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 0
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!L", self.vrf))
+        packed.append(loxi.generic_util.pack_list(self.values))
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vrf_counter_stats_entry()
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 2)
+        reader.skip(2)
+        obj.vrf = reader.read("!L")[0]
+        obj.values = loxi.generic_util.unpack_list(reader, ofp.common.uint64.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.vrf != other.vrf: return False
+        if self.values != other.values: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vrf_counter_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("vrf = ");
+                q.text("%#x" % self.vrf)
+                q.text(","); q.breakable()
+                q.text("values = ");
+                q.pp(self.values)
+            q.breakable()
+        q.text('}')
+
+
+class bucket(loxi.OFObject):
+
+    def __init__(self, weight=None, watch_port=None, watch_group=None, actions=None):
+        if weight != None:
+            self.weight = weight
+        else:
+            self.weight = 0
+        if watch_port != None:
+            self.watch_port = watch_port
+        else:
+            self.watch_port = 0
+        if watch_group != None:
+            self.watch_group = watch_group
+        else:
+            self.watch_group = 0
+        if actions != None:
+            self.actions = actions
+        else:
+            self.actions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 0
+        packed.append(struct.pack("!H", self.weight))
+        packed.append(util.pack_port_no(self.watch_port))
+        packed.append(struct.pack("!L", self.watch_group))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.actions))
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bucket()
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 2)
+        obj.weight = reader.read("!H")[0]
+        obj.watch_port = util.unpack_port_no(reader)
+        obj.watch_group = reader.read("!L")[0]
+        reader.skip(4)
+        obj.actions = loxi.generic_util.unpack_list(reader, ofp.action.action.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.weight != other.weight: return False
+        if self.watch_port != other.watch_port: return False
+        if self.watch_group != other.watch_group: return False
+        if self.actions != other.actions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bucket {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("weight = ");
+                q.text("%#x" % self.weight)
+                q.text(","); q.breakable()
+                q.text("watch_port = ");
+                q.text(util.pretty_port(self.watch_port))
+                q.text(","); q.breakable()
+                q.text("watch_group = ");
+                q.text("%#x" % self.watch_group)
+                q.text(","); q.breakable()
+                q.text("actions = ");
+                q.pp(self.actions)
+            q.breakable()
+        q.text('}')
+
+
+class bucket_counter(loxi.OFObject):
+
+    def __init__(self, packet_count=None, byte_count=None):
+        if packet_count != None:
+            self.packet_count = packet_count
+        else:
+            self.packet_count = 0
+        if byte_count != None:
+            self.byte_count = byte_count
+        else:
+            self.byte_count = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!Q", self.packet_count))
+        packed.append(struct.pack("!Q", self.byte_count))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bucket_counter()
+        obj.packet_count = reader.read("!Q")[0]
+        obj.byte_count = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.packet_count != other.packet_count: return False
+        if self.byte_count != other.byte_count: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bucket_counter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("packet_count = ");
+                q.text("%#x" % self.packet_count)
+                q.text(","); q.breakable()
+                q.text("byte_count = ");
+                q.text("%#x" % self.byte_count)
+            q.breakable()
+        q.text('}')
+
+
+class flow_stats_entry(loxi.OFObject):
+
+    def __init__(self, table_id=None, duration_sec=None, duration_nsec=None, priority=None, idle_timeout=None, hard_timeout=None, flags=None, importance=None, cookie=None, packet_count=None, byte_count=None, match=None, instructions=None):
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if duration_sec != None:
+            self.duration_sec = duration_sec
+        else:
+            self.duration_sec = 0
+        if duration_nsec != None:
+            self.duration_nsec = duration_nsec
+        else:
+            self.duration_nsec = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if importance != None:
+            self.importance = importance
+        else:
+            self.importance = 0
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if packet_count != None:
+            self.packet_count = packet_count
+        else:
+            self.packet_count = 0
+        if byte_count != None:
+            self.byte_count = byte_count
+        else:
+            self.byte_count = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if instructions != None:
+            self.instructions = instructions
+        else:
+            self.instructions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 0
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!L", self.duration_sec))
+        packed.append(struct.pack("!L", self.duration_nsec))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(struct.pack("!H", self.importance))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.packet_count))
+        packed.append(struct.pack("!Q", self.byte_count))
+        packed.append(self.match.pack())
+        packed.append(loxi.generic_util.pack_list(self.instructions))
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_stats_entry()
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 2)
+        obj.table_id = reader.read("!B")[0]
+        reader.skip(1)
+        obj.duration_sec = reader.read("!L")[0]
+        obj.duration_nsec = reader.read("!L")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.flags = reader.read("!H")[0]
+        obj.importance = reader.read("!H")[0]
+        reader.skip(2)
+        obj.cookie = reader.read("!Q")[0]
+        obj.packet_count = reader.read("!Q")[0]
+        obj.byte_count = reader.read("!Q")[0]
+        obj.match = ofp.match.unpack(reader)
+        obj.instructions = loxi.generic_util.unpack_list(reader, ofp.instruction.instruction.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.table_id != other.table_id: return False
+        if self.duration_sec != other.duration_sec: return False
+        if self.duration_nsec != other.duration_nsec: return False
+        if self.priority != other.priority: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.flags != other.flags: return False
+        if self.importance != other.importance: return False
+        if self.cookie != other.cookie: return False
+        if self.packet_count != other.packet_count: return False
+        if self.byte_count != other.byte_count: return False
+        if self.match != other.match: return False
+        if self.instructions != other.instructions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("duration_sec = ");
+                q.text("%#x" % self.duration_sec)
+                q.text(","); q.breakable()
+                q.text("duration_nsec = ");
+                q.text("%#x" % self.duration_nsec)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("importance = ");
+                q.text("%#x" % self.importance)
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("packet_count = ");
+                q.text("%#x" % self.packet_count)
+                q.text(","); q.breakable()
+                q.text("byte_count = ");
+                q.text("%#x" % self.byte_count)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("instructions = ");
+                q.pp(self.instructions)
+            q.breakable()
+        q.text('}')
+
+
+class group_desc_stats_entry(loxi.OFObject):
+
+    def __init__(self, group_type=None, group_id=None, buckets=None):
+        if group_type != None:
+            self.group_type = group_type
+        else:
+            self.group_type = 0
+        if group_id != None:
+            self.group_id = group_id
+        else:
+            self.group_id = 0
+        if buckets != None:
+            self.buckets = buckets
+        else:
+            self.buckets = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 0
+        packed.append(struct.pack("!B", self.group_type))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!L", self.group_id))
+        packed.append(loxi.generic_util.pack_list(self.buckets))
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_desc_stats_entry()
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 2)
+        obj.group_type = reader.read("!B")[0]
+        reader.skip(1)
+        obj.group_id = reader.read("!L")[0]
+        obj.buckets = loxi.generic_util.unpack_list(reader, ofp.common.bucket.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.group_type != other.group_type: return False
+        if self.group_id != other.group_id: return False
+        if self.buckets != other.buckets: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_desc_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("group_type = ");
+                q.text("%#x" % self.group_type)
+                q.text(","); q.breakable()
+                q.text("group_id = ");
+                q.text("%#x" % self.group_id)
+                q.text(","); q.breakable()
+                q.text("buckets = ");
+                q.pp(self.buckets)
+            q.breakable()
+        q.text('}')
+
+
+class group_stats_entry(loxi.OFObject):
+
+    def __init__(self, group_id=None, ref_count=None, packet_count=None, byte_count=None, duration_sec=None, duration_nsec=None, bucket_stats=None):
+        if group_id != None:
+            self.group_id = group_id
+        else:
+            self.group_id = 0
+        if ref_count != None:
+            self.ref_count = ref_count
+        else:
+            self.ref_count = 0
+        if packet_count != None:
+            self.packet_count = packet_count
+        else:
+            self.packet_count = 0
+        if byte_count != None:
+            self.byte_count = byte_count
+        else:
+            self.byte_count = 0
+        if duration_sec != None:
+            self.duration_sec = duration_sec
+        else:
+            self.duration_sec = 0
+        if duration_nsec != None:
+            self.duration_nsec = duration_nsec
+        else:
+            self.duration_nsec = 0
+        if bucket_stats != None:
+            self.bucket_stats = bucket_stats
+        else:
+            self.bucket_stats = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 0
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!L", self.group_id))
+        packed.append(struct.pack("!L", self.ref_count))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!Q", self.packet_count))
+        packed.append(struct.pack("!Q", self.byte_count))
+        packed.append(struct.pack("!L", self.duration_sec))
+        packed.append(struct.pack("!L", self.duration_nsec))
+        packed.append(loxi.generic_util.pack_list(self.bucket_stats))
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_stats_entry()
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 2)
+        reader.skip(2)
+        obj.group_id = reader.read("!L")[0]
+        obj.ref_count = reader.read("!L")[0]
+        reader.skip(4)
+        obj.packet_count = reader.read("!Q")[0]
+        obj.byte_count = reader.read("!Q")[0]
+        obj.duration_sec = reader.read("!L")[0]
+        obj.duration_nsec = reader.read("!L")[0]
+        obj.bucket_stats = loxi.generic_util.unpack_list(reader, ofp.common.bucket_counter.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.group_id != other.group_id: return False
+        if self.ref_count != other.ref_count: return False
+        if self.packet_count != other.packet_count: return False
+        if self.byte_count != other.byte_count: return False
+        if self.duration_sec != other.duration_sec: return False
+        if self.duration_nsec != other.duration_nsec: return False
+        if self.bucket_stats != other.bucket_stats: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("group_id = ");
+                q.text("%#x" % self.group_id)
+                q.text(","); q.breakable()
+                q.text("ref_count = ");
+                q.text("%#x" % self.ref_count)
+                q.text(","); q.breakable()
+                q.text("packet_count = ");
+                q.text("%#x" % self.packet_count)
+                q.text(","); q.breakable()
+                q.text("byte_count = ");
+                q.text("%#x" % self.byte_count)
+                q.text(","); q.breakable()
+                q.text("duration_sec = ");
+                q.text("%#x" % self.duration_sec)
+                q.text(","); q.breakable()
+                q.text("duration_nsec = ");
+                q.text("%#x" % self.duration_nsec)
+                q.text(","); q.breakable()
+                q.text("bucket_stats = ");
+                q.pp(self.bucket_stats)
+            q.breakable()
+        q.text('}')
+
+
+class hello_elem(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = hello_elem.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = hello_elem()
+        obj.type = reader.read("!H")[0]
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("hello_elem {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class hello_elem_versionbitmap(hello_elem):
+    type = 1
+
+    def __init__(self, bitmaps=None):
+        if bitmaps != None:
+            self.bitmaps = bitmaps
+        else:
+            self.bitmaps = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(loxi.generic_util.pack_list(self.bitmaps))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = hello_elem_versionbitmap()
+        _type = reader.read("!H")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.bitmaps = loxi.generic_util.unpack_list(reader, ofp.common.uint32.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.bitmaps != other.bitmaps: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("hello_elem_versionbitmap {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("bitmaps = ");
+                q.pp(self.bitmaps)
+            q.breakable()
+        q.text('}')
+
+hello_elem.subtypes[1] = hello_elem_versionbitmap
+
+class match_v3(loxi.OFObject):
+    type = 1
+
+    def __init__(self, oxm_list=None):
+        if oxm_list != None:
+            self.oxm_list = oxm_list
+        else:
+            self.oxm_list = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(loxi.generic_util.pack_list(self.oxm_list))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        packed.append(loxi.generic_util.pad_to(8, length))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = match_v3()
+        _type = reader.read("!H")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.oxm_list = loxi.generic_util.unpack_list(reader, ofp.oxm.oxm.unpack)
+        orig_reader.skip_align()
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.oxm_list != other.oxm_list: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("match_v3 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("oxm_list = ");
+                q.pp(self.oxm_list)
+            q.breakable()
+        q.text('}')
+
+
+class meter_band_stats(loxi.OFObject):
+
+    def __init__(self, packet_band_count=None, byte_band_count=None):
+        if packet_band_count != None:
+            self.packet_band_count = packet_band_count
+        else:
+            self.packet_band_count = 0
+        if byte_band_count != None:
+            self.byte_band_count = byte_band_count
+        else:
+            self.byte_band_count = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!Q", self.packet_band_count))
+        packed.append(struct.pack("!Q", self.byte_band_count))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = meter_band_stats()
+        obj.packet_band_count = reader.read("!Q")[0]
+        obj.byte_band_count = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.packet_band_count != other.packet_band_count: return False
+        if self.byte_band_count != other.byte_band_count: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("meter_band_stats {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("packet_band_count = ");
+                q.text("%#x" % self.packet_band_count)
+                q.text(","); q.breakable()
+                q.text("byte_band_count = ");
+                q.text("%#x" % self.byte_band_count)
+            q.breakable()
+        q.text('}')
+
+
+class meter_config(loxi.OFObject):
+
+    def __init__(self, flags=None, meter_id=None, entries=None):
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if meter_id != None:
+            self.meter_id = meter_id
+        else:
+            self.meter_id = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 0
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(struct.pack("!L", self.meter_id))
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = meter_config()
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 2)
+        obj.flags = reader.read("!H")[0]
+        obj.meter_id = reader.read("!L")[0]
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.meter_band.meter_band.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.flags != other.flags: return False
+        if self.meter_id != other.meter_id: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("meter_config {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("meter_id = ");
+                q.text("%#x" % self.meter_id)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+
+class meter_features(loxi.OFObject):
+
+    def __init__(self, max_meter=None, band_types=None, capabilities=None, max_bands=None, max_color=None):
+        if max_meter != None:
+            self.max_meter = max_meter
+        else:
+            self.max_meter = 0
+        if band_types != None:
+            self.band_types = band_types
+        else:
+            self.band_types = 0
+        if capabilities != None:
+            self.capabilities = capabilities
+        else:
+            self.capabilities = 0
+        if max_bands != None:
+            self.max_bands = max_bands
+        else:
+            self.max_bands = 0
+        if max_color != None:
+            self.max_color = max_color
+        else:
+            self.max_color = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.max_meter))
+        packed.append(struct.pack("!L", self.band_types))
+        packed.append(struct.pack("!L", self.capabilities))
+        packed.append(struct.pack("!B", self.max_bands))
+        packed.append(struct.pack("!B", self.max_color))
+        packed.append('\x00' * 2)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = meter_features()
+        obj.max_meter = reader.read("!L")[0]
+        obj.band_types = reader.read("!L")[0]
+        obj.capabilities = reader.read("!L")[0]
+        obj.max_bands = reader.read("!B")[0]
+        obj.max_color = reader.read("!B")[0]
+        reader.skip(2)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.max_meter != other.max_meter: return False
+        if self.band_types != other.band_types: return False
+        if self.capabilities != other.capabilities: return False
+        if self.max_bands != other.max_bands: return False
+        if self.max_color != other.max_color: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("meter_features {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("max_meter = ");
+                q.text("%#x" % self.max_meter)
+                q.text(","); q.breakable()
+                q.text("band_types = ");
+                q.text("%#x" % self.band_types)
+                q.text(","); q.breakable()
+                q.text("capabilities = ");
+                q.text("%#x" % self.capabilities)
+                q.text(","); q.breakable()
+                q.text("max_bands = ");
+                q.text("%#x" % self.max_bands)
+                q.text(","); q.breakable()
+                q.text("max_color = ");
+                q.text("%#x" % self.max_color)
+            q.breakable()
+        q.text('}')
+
+
+class meter_stats(loxi.OFObject):
+
+    def __init__(self, meter_id=None, flow_count=None, packet_in_count=None, byte_in_count=None, duration_sec=None, duration_nsec=None, band_stats=None):
+        if meter_id != None:
+            self.meter_id = meter_id
+        else:
+            self.meter_id = 0
+        if flow_count != None:
+            self.flow_count = flow_count
+        else:
+            self.flow_count = 0
+        if packet_in_count != None:
+            self.packet_in_count = packet_in_count
+        else:
+            self.packet_in_count = 0
+        if byte_in_count != None:
+            self.byte_in_count = byte_in_count
+        else:
+            self.byte_in_count = 0
+        if duration_sec != None:
+            self.duration_sec = duration_sec
+        else:
+            self.duration_sec = 0
+        if duration_nsec != None:
+            self.duration_nsec = duration_nsec
+        else:
+            self.duration_nsec = 0
+        if band_stats != None:
+            self.band_stats = band_stats
+        else:
+            self.band_stats = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.meter_id))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 6)
+        packed.append(struct.pack("!L", self.flow_count))
+        packed.append(struct.pack("!Q", self.packet_in_count))
+        packed.append(struct.pack("!Q", self.byte_in_count))
+        packed.append(struct.pack("!L", self.duration_sec))
+        packed.append(struct.pack("!L", self.duration_nsec))
+        packed.append(loxi.generic_util.pack_list(self.band_stats))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = meter_stats()
+        obj.meter_id = reader.read("!L")[0]
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 6)
+        reader.skip(6)
+        obj.flow_count = reader.read("!L")[0]
+        obj.packet_in_count = reader.read("!Q")[0]
+        obj.byte_in_count = reader.read("!Q")[0]
+        obj.duration_sec = reader.read("!L")[0]
+        obj.duration_nsec = reader.read("!L")[0]
+        obj.band_stats = loxi.generic_util.unpack_list(reader, ofp.common.meter_band_stats.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.meter_id != other.meter_id: return False
+        if self.flow_count != other.flow_count: return False
+        if self.packet_in_count != other.packet_in_count: return False
+        if self.byte_in_count != other.byte_in_count: return False
+        if self.duration_sec != other.duration_sec: return False
+        if self.duration_nsec != other.duration_nsec: return False
+        if self.band_stats != other.band_stats: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("meter_stats {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("meter_id = ");
+                q.text("%#x" % self.meter_id)
+                q.text(","); q.breakable()
+                q.text("flow_count = ");
+                q.text("%#x" % self.flow_count)
+                q.text(","); q.breakable()
+                q.text("packet_in_count = ");
+                q.text("%#x" % self.packet_in_count)
+                q.text(","); q.breakable()
+                q.text("byte_in_count = ");
+                q.text("%#x" % self.byte_in_count)
+                q.text(","); q.breakable()
+                q.text("duration_sec = ");
+                q.text("%#x" % self.duration_sec)
+                q.text(","); q.breakable()
+                q.text("duration_nsec = ");
+                q.text("%#x" % self.duration_nsec)
+                q.text(","); q.breakable()
+                q.text("band_stats = ");
+                q.pp(self.band_stats)
+            q.breakable()
+        q.text('}')
+
+
+class packet_queue(loxi.OFObject):
+
+    def __init__(self, queue_id=None, port=None, properties=None):
+        if queue_id != None:
+            self.queue_id = queue_id
+        else:
+            self.queue_id = 0
+        if port != None:
+            self.port = port
+        else:
+            self.port = 0
+        if properties != None:
+            self.properties = properties
+        else:
+            self.properties = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.queue_id))
+        packed.append(util.pack_port_no(self.port))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 2
+        packed.append('\x00' * 6)
+        packed.append(loxi.generic_util.pack_list(self.properties))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = packet_queue()
+        obj.queue_id = reader.read("!L")[0]
+        obj.port = util.unpack_port_no(reader)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 10)
+        reader.skip(6)
+        obj.properties = loxi.generic_util.unpack_list(reader, ofp.common.queue_prop.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.queue_id != other.queue_id: return False
+        if self.port != other.port: return False
+        if self.properties != other.properties: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("packet_queue {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("queue_id = ");
+                q.text("%#x" % self.queue_id)
+                q.text(","); q.breakable()
+                q.text("port = ");
+                q.text(util.pretty_port(self.port))
+                q.text(","); q.breakable()
+                q.text("properties = ");
+                q.pp(self.properties)
+            q.breakable()
+        q.text('}')
+
+
+class port_desc(loxi.OFObject):
+
+    def __init__(self, port_no=None, hw_addr=None, name=None, config=None, state=None, properties=None):
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if hw_addr != None:
+            self.hw_addr = hw_addr
+        else:
+            self.hw_addr = [0,0,0,0,0,0]
+        if name != None:
+            self.name = name
+        else:
+            self.name = ""
+        if config != None:
+            self.config = config
+        else:
+            self.config = 0
+        if state != None:
+            self.state = state
+        else:
+            self.state = 0
+        if properties != None:
+            self.properties = properties
+        else:
+            self.properties = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!6B", *self.hw_addr))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!16s", self.name))
+        packed.append(struct.pack("!L", self.config))
+        packed.append(struct.pack("!L", self.state))
+        packed.append(loxi.generic_util.pack_list(self.properties))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_desc()
+        obj.port_no = util.unpack_port_no(reader)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 6)
+        reader.skip(2)
+        obj.hw_addr = list(reader.read('!6B'))
+        reader.skip(2)
+        obj.name = reader.read("!16s")[0].rstrip("\x00")
+        obj.config = reader.read("!L")[0]
+        obj.state = reader.read("!L")[0]
+        obj.properties = loxi.generic_util.unpack_list(reader, ofp.port_desc_prop.port_desc_prop.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.port_no != other.port_no: return False
+        if self.hw_addr != other.hw_addr: return False
+        if self.name != other.name: return False
+        if self.config != other.config: return False
+        if self.state != other.state: return False
+        if self.properties != other.properties: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_desc {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("hw_addr = ");
+                q.text(util.pretty_mac(self.hw_addr))
+                q.text(","); q.breakable()
+                q.text("name = ");
+                q.pp(self.name)
+                q.text(","); q.breakable()
+                q.text("config = ");
+                q.text("%#x" % self.config)
+                q.text(","); q.breakable()
+                q.text("state = ");
+                q.text("%#x" % self.state)
+                q.text(","); q.breakable()
+                q.text("properties = ");
+                q.pp(self.properties)
+            q.breakable()
+        q.text('}')
+
+
+class port_stats_entry(loxi.OFObject):
+
+    def __init__(self, port_no=None, duration_sec=None, duration_nsec=None, rx_packets=None, tx_packets=None, rx_bytes=None, tx_bytes=None, rx_dropped=None, tx_dropped=None, rx_errors=None, tx_errors=None, properties=None):
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if duration_sec != None:
+            self.duration_sec = duration_sec
+        else:
+            self.duration_sec = 0
+        if duration_nsec != None:
+            self.duration_nsec = duration_nsec
+        else:
+            self.duration_nsec = 0
+        if rx_packets != None:
+            self.rx_packets = rx_packets
+        else:
+            self.rx_packets = 0
+        if tx_packets != None:
+            self.tx_packets = tx_packets
+        else:
+            self.tx_packets = 0
+        if rx_bytes != None:
+            self.rx_bytes = rx_bytes
+        else:
+            self.rx_bytes = 0
+        if tx_bytes != None:
+            self.tx_bytes = tx_bytes
+        else:
+            self.tx_bytes = 0
+        if rx_dropped != None:
+            self.rx_dropped = rx_dropped
+        else:
+            self.rx_dropped = 0
+        if tx_dropped != None:
+            self.tx_dropped = tx_dropped
+        else:
+            self.tx_dropped = 0
+        if rx_errors != None:
+            self.rx_errors = rx_errors
+        else:
+            self.rx_errors = 0
+        if tx_errors != None:
+            self.tx_errors = tx_errors
+        else:
+            self.tx_errors = 0
+        if properties != None:
+            self.properties = properties
+        else:
+            self.properties = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 0
+        packed.append('\x00' * 2)
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!L", self.duration_sec))
+        packed.append(struct.pack("!L", self.duration_nsec))
+        packed.append(struct.pack("!Q", self.rx_packets))
+        packed.append(struct.pack("!Q", self.tx_packets))
+        packed.append(struct.pack("!Q", self.rx_bytes))
+        packed.append(struct.pack("!Q", self.tx_bytes))
+        packed.append(struct.pack("!Q", self.rx_dropped))
+        packed.append(struct.pack("!Q", self.tx_dropped))
+        packed.append(struct.pack("!Q", self.rx_errors))
+        packed.append(struct.pack("!Q", self.tx_errors))
+        packed.append(loxi.generic_util.pack_list(self.properties))
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_stats_entry()
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 2)
+        reader.skip(2)
+        obj.port_no = util.unpack_port_no(reader)
+        obj.duration_sec = reader.read("!L")[0]
+        obj.duration_nsec = reader.read("!L")[0]
+        obj.rx_packets = reader.read("!Q")[0]
+        obj.tx_packets = reader.read("!Q")[0]
+        obj.rx_bytes = reader.read("!Q")[0]
+        obj.tx_bytes = reader.read("!Q")[0]
+        obj.rx_dropped = reader.read("!Q")[0]
+        obj.tx_dropped = reader.read("!Q")[0]
+        obj.rx_errors = reader.read("!Q")[0]
+        obj.tx_errors = reader.read("!Q")[0]
+        obj.properties = loxi.generic_util.unpack_list(reader, ofp.port_stats_prop.port_stats_prop.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.port_no != other.port_no: return False
+        if self.duration_sec != other.duration_sec: return False
+        if self.duration_nsec != other.duration_nsec: return False
+        if self.rx_packets != other.rx_packets: return False
+        if self.tx_packets != other.tx_packets: return False
+        if self.rx_bytes != other.rx_bytes: return False
+        if self.tx_bytes != other.tx_bytes: return False
+        if self.rx_dropped != other.rx_dropped: return False
+        if self.tx_dropped != other.tx_dropped: return False
+        if self.rx_errors != other.rx_errors: return False
+        if self.tx_errors != other.tx_errors: return False
+        if self.properties != other.properties: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("duration_sec = ");
+                q.text("%#x" % self.duration_sec)
+                q.text(","); q.breakable()
+                q.text("duration_nsec = ");
+                q.text("%#x" % self.duration_nsec)
+                q.text(","); q.breakable()
+                q.text("rx_packets = ");
+                q.text("%#x" % self.rx_packets)
+                q.text(","); q.breakable()
+                q.text("tx_packets = ");
+                q.text("%#x" % self.tx_packets)
+                q.text(","); q.breakable()
+                q.text("rx_bytes = ");
+                q.text("%#x" % self.rx_bytes)
+                q.text(","); q.breakable()
+                q.text("tx_bytes = ");
+                q.text("%#x" % self.tx_bytes)
+                q.text(","); q.breakable()
+                q.text("rx_dropped = ");
+                q.text("%#x" % self.rx_dropped)
+                q.text(","); q.breakable()
+                q.text("tx_dropped = ");
+                q.text("%#x" % self.tx_dropped)
+                q.text(","); q.breakable()
+                q.text("rx_errors = ");
+                q.text("%#x" % self.rx_errors)
+                q.text(","); q.breakable()
+                q.text("tx_errors = ");
+                q.text("%#x" % self.tx_errors)
+                q.text(","); q.breakable()
+                q.text("properties = ");
+                q.pp(self.properties)
+            q.breakable()
+        q.text('}')
+
+
+class queue_desc(loxi.OFObject):
+
+    def __init__(self, port_no=None, queue_id=None, properties=None):
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if queue_id != None:
+            self.queue_id = queue_id
+        else:
+            self.queue_id = 0
+        if properties != None:
+            self.properties = properties
+        else:
+            self.properties = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.port_no))
+        packed.append(struct.pack("!L", self.queue_id))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append('\x00' * 6)
+        packed.append(loxi.generic_util.pack_list(self.properties))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_desc()
+        obj.port_no = reader.read("!L")[0]
+        obj.queue_id = reader.read("!L")[0]
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 10)
+        reader.skip(6)
+        obj.properties = loxi.generic_util.unpack_list(reader, ofp.queue_desc_prop.queue_desc_prop.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.port_no != other.port_no: return False
+        if self.queue_id != other.queue_id: return False
+        if self.properties != other.properties: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_desc {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("port_no = ");
+                q.text("%#x" % self.port_no)
+                q.text(","); q.breakable()
+                q.text("queue_id = ");
+                q.text("%#x" % self.queue_id)
+                q.text(","); q.breakable()
+                q.text("properties = ");
+                q.pp(self.properties)
+            q.breakable()
+        q.text('}')
+
+
+class queue_prop(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = queue_prop.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = queue_prop()
+        obj.type = reader.read("!H")[0]
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_prop {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class queue_prop_experimenter(queue_prop):
+    subtypes = {}
+
+    type = 65535
+
+    def __init__(self, experimenter=None, data=None):
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append('\x00' * 4)
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 8)
+        subclass = queue_prop_experimenter.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = queue_prop_experimenter()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        obj.experimenter = reader.read("!L")[0]
+        reader.skip(4)
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.experimenter != other.experimenter: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_prop_experimenter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+queue_prop.subtypes[65535] = queue_prop_experimenter
+
+class queue_prop_max_rate(queue_prop):
+    type = 2
+
+    def __init__(self, rate=None):
+        if rate != None:
+            self.rate = rate
+        else:
+            self.rate = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!H", self.rate))
+        packed.append('\x00' * 6)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_prop_max_rate()
+        _type = reader.read("!H")[0]
+        assert(_type == 2)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        obj.rate = reader.read("!H")[0]
+        reader.skip(6)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.rate != other.rate: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_prop_max_rate {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("rate = ");
+                q.text("%#x" % self.rate)
+            q.breakable()
+        q.text('}')
+
+queue_prop.subtypes[2] = queue_prop_max_rate
+
+class queue_prop_min_rate(queue_prop):
+    type = 1
+
+    def __init__(self, rate=None):
+        if rate != None:
+            self.rate = rate
+        else:
+            self.rate = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!H", self.rate))
+        packed.append('\x00' * 6)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_prop_min_rate()
+        _type = reader.read("!H")[0]
+        assert(_type == 1)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        obj.rate = reader.read("!H")[0]
+        reader.skip(6)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.rate != other.rate: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_prop_min_rate {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("rate = ");
+                q.text("%#x" % self.rate)
+            q.breakable()
+        q.text('}')
+
+queue_prop.subtypes[1] = queue_prop_min_rate
+
+class queue_stats_entry(loxi.OFObject):
+
+    def __init__(self, port_no=None, queue_id=None, tx_bytes=None, tx_packets=None, tx_errors=None, duration_sec=None, duration_nsec=None, properties=None):
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if queue_id != None:
+            self.queue_id = queue_id
+        else:
+            self.queue_id = 0
+        if tx_bytes != None:
+            self.tx_bytes = tx_bytes
+        else:
+            self.tx_bytes = 0
+        if tx_packets != None:
+            self.tx_packets = tx_packets
+        else:
+            self.tx_packets = 0
+        if tx_errors != None:
+            self.tx_errors = tx_errors
+        else:
+            self.tx_errors = 0
+        if duration_sec != None:
+            self.duration_sec = duration_sec
+        else:
+            self.duration_sec = 0
+        if duration_nsec != None:
+            self.duration_nsec = duration_nsec
+        else:
+            self.duration_nsec = 0
+        if properties != None:
+            self.properties = properties
+        else:
+            self.properties = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 0
+        packed.append('\x00' * 6)
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!L", self.queue_id))
+        packed.append(struct.pack("!Q", self.tx_bytes))
+        packed.append(struct.pack("!Q", self.tx_packets))
+        packed.append(struct.pack("!Q", self.tx_errors))
+        packed.append(struct.pack("!L", self.duration_sec))
+        packed.append(struct.pack("!L", self.duration_nsec))
+        packed.append(loxi.generic_util.pack_list(self.properties))
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_stats_entry()
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 2)
+        reader.skip(6)
+        obj.port_no = util.unpack_port_no(reader)
+        obj.queue_id = reader.read("!L")[0]
+        obj.tx_bytes = reader.read("!Q")[0]
+        obj.tx_packets = reader.read("!Q")[0]
+        obj.tx_errors = reader.read("!Q")[0]
+        obj.duration_sec = reader.read("!L")[0]
+        obj.duration_nsec = reader.read("!L")[0]
+        obj.properties = loxi.generic_util.unpack_list(reader, ofp.queue_stats_prop.queue_stats_prop.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.port_no != other.port_no: return False
+        if self.queue_id != other.queue_id: return False
+        if self.tx_bytes != other.tx_bytes: return False
+        if self.tx_packets != other.tx_packets: return False
+        if self.tx_errors != other.tx_errors: return False
+        if self.duration_sec != other.duration_sec: return False
+        if self.duration_nsec != other.duration_nsec: return False
+        if self.properties != other.properties: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("queue_id = ");
+                q.text("%#x" % self.queue_id)
+                q.text(","); q.breakable()
+                q.text("tx_bytes = ");
+                q.text("%#x" % self.tx_bytes)
+                q.text(","); q.breakable()
+                q.text("tx_packets = ");
+                q.text("%#x" % self.tx_packets)
+                q.text(","); q.breakable()
+                q.text("tx_errors = ");
+                q.text("%#x" % self.tx_errors)
+                q.text(","); q.breakable()
+                q.text("duration_sec = ");
+                q.text("%#x" % self.duration_sec)
+                q.text(","); q.breakable()
+                q.text("duration_nsec = ");
+                q.text("%#x" % self.duration_nsec)
+                q.text(","); q.breakable()
+                q.text("properties = ");
+                q.pp(self.properties)
+            q.breakable()
+        q.text('}')
+
+
+class table_desc(loxi.OFObject):
+
+    def __init__(self, table_id=None, config=None):
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if config != None:
+            self.config = config
+        else:
+            self.config = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 0
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!L", self.config))
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_desc()
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 2)
+        obj.table_id = reader.read("!B")[0]
+        reader.skip(1)
+        obj.config = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.table_id != other.table_id: return False
+        if self.config != other.config: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_desc {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("config = ");
+                q.text("%#x" % self.config)
+            q.breakable()
+        q.text('}')
+
+
+class table_feature_prop(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = table_feature_prop.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = table_feature_prop()
+        obj.type = reader.read("!H")[0]
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_feature_prop {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class table_feature_prop_apply_actions(table_feature_prop):
+    type = 6
+
+    def __init__(self, action_ids=None):
+        if action_ids != None:
+            self.action_ids = action_ids
+        else:
+            self.action_ids = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(loxi.generic_util.pack_list(self.action_ids))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_feature_prop_apply_actions()
+        _type = reader.read("!H")[0]
+        assert(_type == 6)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.action_ids = loxi.generic_util.unpack_list(reader, ofp.action_id.action_id.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.action_ids != other.action_ids: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_feature_prop_apply_actions {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("action_ids = ");
+                q.pp(self.action_ids)
+            q.breakable()
+        q.text('}')
+
+table_feature_prop.subtypes[6] = table_feature_prop_apply_actions
+
+class table_feature_prop_apply_actions_miss(table_feature_prop):
+    type = 7
+
+    def __init__(self, action_ids=None):
+        if action_ids != None:
+            self.action_ids = action_ids
+        else:
+            self.action_ids = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(loxi.generic_util.pack_list(self.action_ids))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_feature_prop_apply_actions_miss()
+        _type = reader.read("!H")[0]
+        assert(_type == 7)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.action_ids = loxi.generic_util.unpack_list(reader, ofp.action_id.action_id.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.action_ids != other.action_ids: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_feature_prop_apply_actions_miss {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("action_ids = ");
+                q.pp(self.action_ids)
+            q.breakable()
+        q.text('}')
+
+table_feature_prop.subtypes[7] = table_feature_prop_apply_actions_miss
+
+class table_feature_prop_apply_setfield(table_feature_prop):
+    type = 14
+
+    def __init__(self, oxm_ids=None):
+        if oxm_ids != None:
+            self.oxm_ids = oxm_ids
+        else:
+            self.oxm_ids = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(loxi.generic_util.pack_list(self.oxm_ids))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_feature_prop_apply_setfield()
+        _type = reader.read("!H")[0]
+        assert(_type == 14)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.oxm_ids = loxi.generic_util.unpack_list(reader, ofp.common.uint32.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.oxm_ids != other.oxm_ids: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_feature_prop_apply_setfield {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("oxm_ids = ");
+                q.pp(self.oxm_ids)
+            q.breakable()
+        q.text('}')
+
+table_feature_prop.subtypes[14] = table_feature_prop_apply_setfield
+
+class table_feature_prop_apply_setfield_miss(table_feature_prop):
+    type = 15
+
+    def __init__(self, oxm_ids=None):
+        if oxm_ids != None:
+            self.oxm_ids = oxm_ids
+        else:
+            self.oxm_ids = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(loxi.generic_util.pack_list(self.oxm_ids))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_feature_prop_apply_setfield_miss()
+        _type = reader.read("!H")[0]
+        assert(_type == 15)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.oxm_ids = loxi.generic_util.unpack_list(reader, ofp.common.uint32.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.oxm_ids != other.oxm_ids: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_feature_prop_apply_setfield_miss {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("oxm_ids = ");
+                q.pp(self.oxm_ids)
+            q.breakable()
+        q.text('}')
+
+table_feature_prop.subtypes[15] = table_feature_prop_apply_setfield_miss
+
+class table_feature_prop_experimenter(table_feature_prop):
+    subtypes = {}
+
+    type = 65534
+
+    def __init__(self, experimenter=None, subtype=None, experimenter_data=None):
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        if experimenter_data != None:
+            self.experimenter_data = experimenter_data
+        else:
+            self.experimenter_data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(self.experimenter_data)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 4)
+        subclass = table_feature_prop_experimenter.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = table_feature_prop_experimenter()
+        _type = reader.read("!H")[0]
+        assert(_type == 65534)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.experimenter = reader.read("!L")[0]
+        obj.subtype = reader.read("!L")[0]
+        obj.experimenter_data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.experimenter != other.experimenter: return False
+        if self.subtype != other.subtype: return False
+        if self.experimenter_data != other.experimenter_data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_feature_prop_experimenter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("subtype = ");
+                q.text("%#x" % self.subtype)
+                q.text(","); q.breakable()
+                q.text("experimenter_data = ");
+                q.pp(self.experimenter_data)
+            q.breakable()
+        q.text('}')
+
+table_feature_prop.subtypes[65534] = table_feature_prop_experimenter
+
+class table_feature_prop_experimenter_miss(table_feature_prop):
+    subtypes = {}
+
+    type = 65535
+
+    def __init__(self, experimenter=None, subtype=None, experimenter_data=None):
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        if experimenter_data != None:
+            self.experimenter_data = experimenter_data
+        else:
+            self.experimenter_data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(self.experimenter_data)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 4)
+        subclass = table_feature_prop_experimenter_miss.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = table_feature_prop_experimenter_miss()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.experimenter = reader.read("!L")[0]
+        obj.subtype = reader.read("!L")[0]
+        obj.experimenter_data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.experimenter != other.experimenter: return False
+        if self.subtype != other.subtype: return False
+        if self.experimenter_data != other.experimenter_data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_feature_prop_experimenter_miss {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("subtype = ");
+                q.text("%#x" % self.subtype)
+                q.text(","); q.breakable()
+                q.text("experimenter_data = ");
+                q.pp(self.experimenter_data)
+            q.breakable()
+        q.text('}')
+
+table_feature_prop.subtypes[65535] = table_feature_prop_experimenter_miss
+
+class table_feature_prop_instructions(table_feature_prop):
+    type = 0
+
+    def __init__(self, instruction_ids=None):
+        if instruction_ids != None:
+            self.instruction_ids = instruction_ids
+        else:
+            self.instruction_ids = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(loxi.generic_util.pack_list(self.instruction_ids))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_feature_prop_instructions()
+        _type = reader.read("!H")[0]
+        assert(_type == 0)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.instruction_ids = loxi.generic_util.unpack_list(reader, ofp.instruction_id.instruction_id.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.instruction_ids != other.instruction_ids: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_feature_prop_instructions {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("instruction_ids = ");
+                q.pp(self.instruction_ids)
+            q.breakable()
+        q.text('}')
+
+table_feature_prop.subtypes[0] = table_feature_prop_instructions
+
+class table_feature_prop_instructions_miss(table_feature_prop):
+    type = 1
+
+    def __init__(self, instruction_ids=None):
+        if instruction_ids != None:
+            self.instruction_ids = instruction_ids
+        else:
+            self.instruction_ids = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(loxi.generic_util.pack_list(self.instruction_ids))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_feature_prop_instructions_miss()
+        _type = reader.read("!H")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.instruction_ids = loxi.generic_util.unpack_list(reader, ofp.instruction_id.instruction_id.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.instruction_ids != other.instruction_ids: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_feature_prop_instructions_miss {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("instruction_ids = ");
+                q.pp(self.instruction_ids)
+            q.breakable()
+        q.text('}')
+
+table_feature_prop.subtypes[1] = table_feature_prop_instructions_miss
+
+class table_feature_prop_match(table_feature_prop):
+    type = 8
+
+    def __init__(self, oxm_ids=None):
+        if oxm_ids != None:
+            self.oxm_ids = oxm_ids
+        else:
+            self.oxm_ids = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(loxi.generic_util.pack_list(self.oxm_ids))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_feature_prop_match()
+        _type = reader.read("!H")[0]
+        assert(_type == 8)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.oxm_ids = loxi.generic_util.unpack_list(reader, ofp.common.uint32.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.oxm_ids != other.oxm_ids: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_feature_prop_match {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("oxm_ids = ");
+                q.pp(self.oxm_ids)
+            q.breakable()
+        q.text('}')
+
+table_feature_prop.subtypes[8] = table_feature_prop_match
+
+class table_feature_prop_next_tables(table_feature_prop):
+    type = 2
+
+    def __init__(self, next_table_ids=None):
+        if next_table_ids != None:
+            self.next_table_ids = next_table_ids
+        else:
+            self.next_table_ids = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(loxi.generic_util.pack_list(self.next_table_ids))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_feature_prop_next_tables()
+        _type = reader.read("!H")[0]
+        assert(_type == 2)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.next_table_ids = loxi.generic_util.unpack_list(reader, ofp.common.uint8.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.next_table_ids != other.next_table_ids: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_feature_prop_next_tables {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("next_table_ids = ");
+                q.pp(self.next_table_ids)
+            q.breakable()
+        q.text('}')
+
+table_feature_prop.subtypes[2] = table_feature_prop_next_tables
+
+class table_feature_prop_next_tables_miss(table_feature_prop):
+    type = 3
+
+    def __init__(self, next_table_ids=None):
+        if next_table_ids != None:
+            self.next_table_ids = next_table_ids
+        else:
+            self.next_table_ids = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(loxi.generic_util.pack_list(self.next_table_ids))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_feature_prop_next_tables_miss()
+        _type = reader.read("!H")[0]
+        assert(_type == 3)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.next_table_ids = loxi.generic_util.unpack_list(reader, ofp.common.uint8.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.next_table_ids != other.next_table_ids: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_feature_prop_next_tables_miss {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("next_table_ids = ");
+                q.pp(self.next_table_ids)
+            q.breakable()
+        q.text('}')
+
+table_feature_prop.subtypes[3] = table_feature_prop_next_tables_miss
+
+class table_feature_prop_table_sync_from(table_feature_prop):
+    type = 16
+
+    def __init__(self, table_ids=None):
+        if table_ids != None:
+            self.table_ids = table_ids
+        else:
+            self.table_ids = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(loxi.generic_util.pack_list(self.table_ids))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_feature_prop_table_sync_from()
+        _type = reader.read("!H")[0]
+        assert(_type == 16)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.table_ids = loxi.generic_util.unpack_list(reader, ofp.common.uint8.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.table_ids != other.table_ids: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_feature_prop_table_sync_from {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("table_ids = ");
+                q.pp(self.table_ids)
+            q.breakable()
+        q.text('}')
+
+table_feature_prop.subtypes[16] = table_feature_prop_table_sync_from
+
+class table_feature_prop_wildcards(table_feature_prop):
+    type = 10
+
+    def __init__(self, oxm_ids=None):
+        if oxm_ids != None:
+            self.oxm_ids = oxm_ids
+        else:
+            self.oxm_ids = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(loxi.generic_util.pack_list(self.oxm_ids))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_feature_prop_wildcards()
+        _type = reader.read("!H")[0]
+        assert(_type == 10)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.oxm_ids = loxi.generic_util.unpack_list(reader, ofp.common.uint32.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.oxm_ids != other.oxm_ids: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_feature_prop_wildcards {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("oxm_ids = ");
+                q.pp(self.oxm_ids)
+            q.breakable()
+        q.text('}')
+
+table_feature_prop.subtypes[10] = table_feature_prop_wildcards
+
+class table_feature_prop_write_actions(table_feature_prop):
+    type = 4
+
+    def __init__(self, action_ids=None):
+        if action_ids != None:
+            self.action_ids = action_ids
+        else:
+            self.action_ids = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(loxi.generic_util.pack_list(self.action_ids))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_feature_prop_write_actions()
+        _type = reader.read("!H")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.action_ids = loxi.generic_util.unpack_list(reader, ofp.action_id.action_id.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.action_ids != other.action_ids: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_feature_prop_write_actions {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("action_ids = ");
+                q.pp(self.action_ids)
+            q.breakable()
+        q.text('}')
+
+table_feature_prop.subtypes[4] = table_feature_prop_write_actions
+
+class table_feature_prop_write_actions_miss(table_feature_prop):
+    type = 5
+
+    def __init__(self, action_ids=None):
+        if action_ids != None:
+            self.action_ids = action_ids
+        else:
+            self.action_ids = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(loxi.generic_util.pack_list(self.action_ids))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_feature_prop_write_actions_miss()
+        _type = reader.read("!H")[0]
+        assert(_type == 5)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.action_ids = loxi.generic_util.unpack_list(reader, ofp.action_id.action_id.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.action_ids != other.action_ids: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_feature_prop_write_actions_miss {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("action_ids = ");
+                q.pp(self.action_ids)
+            q.breakable()
+        q.text('}')
+
+table_feature_prop.subtypes[5] = table_feature_prop_write_actions_miss
+
+class table_feature_prop_write_setfield(table_feature_prop):
+    type = 12
+
+    def __init__(self, oxm_ids=None):
+        if oxm_ids != None:
+            self.oxm_ids = oxm_ids
+        else:
+            self.oxm_ids = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(loxi.generic_util.pack_list(self.oxm_ids))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_feature_prop_write_setfield()
+        _type = reader.read("!H")[0]
+        assert(_type == 12)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.oxm_ids = loxi.generic_util.unpack_list(reader, ofp.common.uint32.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.oxm_ids != other.oxm_ids: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_feature_prop_write_setfield {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("oxm_ids = ");
+                q.pp(self.oxm_ids)
+            q.breakable()
+        q.text('}')
+
+table_feature_prop.subtypes[12] = table_feature_prop_write_setfield
+
+class table_feature_prop_write_setfield_miss(table_feature_prop):
+    type = 13
+
+    def __init__(self, oxm_ids=None):
+        if oxm_ids != None:
+            self.oxm_ids = oxm_ids
+        else:
+            self.oxm_ids = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(loxi.generic_util.pack_list(self.oxm_ids))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_feature_prop_write_setfield_miss()
+        _type = reader.read("!H")[0]
+        assert(_type == 13)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.oxm_ids = loxi.generic_util.unpack_list(reader, ofp.common.uint32.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.oxm_ids != other.oxm_ids: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_feature_prop_write_setfield_miss {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("oxm_ids = ");
+                q.pp(self.oxm_ids)
+            q.breakable()
+        q.text('}')
+
+table_feature_prop.subtypes[13] = table_feature_prop_write_setfield_miss
+
+class table_features(loxi.OFObject):
+
+    def __init__(self, table_id=None, name=None, metadata_match=None, metadata_write=None, config=None, max_entries=None, properties=None):
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if name != None:
+            self.name = name
+        else:
+            self.name = ""
+        if metadata_match != None:
+            self.metadata_match = metadata_match
+        else:
+            self.metadata_match = 0
+        if metadata_write != None:
+            self.metadata_write = metadata_write
+        else:
+            self.metadata_write = 0
+        if config != None:
+            self.config = config
+        else:
+            self.config = 0
+        if max_entries != None:
+            self.max_entries = max_entries
+        else:
+            self.max_entries = 0
+        if properties != None:
+            self.properties = properties
+        else:
+            self.properties = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 0
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append('\x00' * 5)
+        packed.append(struct.pack("!32s", self.name))
+        packed.append(struct.pack("!Q", self.metadata_match))
+        packed.append(struct.pack("!Q", self.metadata_write))
+        packed.append(struct.pack("!L", self.config))
+        packed.append(struct.pack("!L", self.max_entries))
+        packed.append(loxi.generic_util.pack_list(self.properties))
+        length = sum([len(x) for x in packed])
+        packed[0] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_features()
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 2)
+        obj.table_id = reader.read("!B")[0]
+        reader.skip(5)
+        obj.name = reader.read("!32s")[0].rstrip("\x00")
+        obj.metadata_match = reader.read("!Q")[0]
+        obj.metadata_write = reader.read("!Q")[0]
+        obj.config = reader.read("!L")[0]
+        obj.max_entries = reader.read("!L")[0]
+        obj.properties = loxi.generic_util.unpack_list(reader, ofp.common.table_feature_prop.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.table_id != other.table_id: return False
+        if self.name != other.name: return False
+        if self.metadata_match != other.metadata_match: return False
+        if self.metadata_write != other.metadata_write: return False
+        if self.config != other.config: return False
+        if self.max_entries != other.max_entries: return False
+        if self.properties != other.properties: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_features {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("name = ");
+                q.pp(self.name)
+                q.text(","); q.breakable()
+                q.text("metadata_match = ");
+                q.text("%#x" % self.metadata_match)
+                q.text(","); q.breakable()
+                q.text("metadata_write = ");
+                q.text("%#x" % self.metadata_write)
+                q.text(","); q.breakable()
+                q.text("config = ");
+                q.text("%#x" % self.config)
+                q.text(","); q.breakable()
+                q.text("max_entries = ");
+                q.text("%#x" % self.max_entries)
+                q.text(","); q.breakable()
+                q.text("properties = ");
+                q.pp(self.properties)
+            q.breakable()
+        q.text('}')
+
+
+class table_mod_prop_eviction(loxi.OFObject):
+    type = 2
+
+    def __init__(self, flags=None):
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.flags))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_mod_prop_eviction()
+        _type = reader.read("!H")[0]
+        assert(_type == 2)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.flags = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_mod_prop_eviction {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+
+class table_mod_prop_experimenter(loxi.OFObject):
+    subtypes = {}
+
+    type = 65535
+
+    def __init__(self, experimenter=None, exp_type=None):
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if exp_type != None:
+            self.exp_type = exp_type
+        else:
+            self.exp_type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.exp_type))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 4)
+        subclass = table_mod_prop_experimenter.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = table_mod_prop_experimenter()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.experimenter = reader.read("!L")[0]
+        obj.exp_type = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.experimenter != other.experimenter: return False
+        if self.exp_type != other.exp_type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_mod_prop_experimenter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("exp_type = ");
+                q.text("%#x" % self.exp_type)
+            q.breakable()
+        q.text('}')
+
+
+class table_mod_prop_vacancy(loxi.OFObject):
+    type = 3
+
+    def __init__(self, vacancy_down=None, vacancy_up=None, vacancy=None):
+        if vacancy_down != None:
+            self.vacancy_down = vacancy_down
+        else:
+            self.vacancy_down = 0
+        if vacancy_up != None:
+            self.vacancy_up = vacancy_up
+        else:
+            self.vacancy_up = 0
+        if vacancy != None:
+            self.vacancy = vacancy
+        else:
+            self.vacancy = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!B", self.vacancy_down))
+        packed.append(struct.pack("!B", self.vacancy_up))
+        packed.append(struct.pack("!B", self.vacancy))
+        packed.append('\x00' * 1)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_mod_prop_vacancy()
+        _type = reader.read("!H")[0]
+        assert(_type == 3)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.vacancy_down = reader.read("!B")[0]
+        obj.vacancy_up = reader.read("!B")[0]
+        obj.vacancy = reader.read("!B")[0]
+        reader.skip(1)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.vacancy_down != other.vacancy_down: return False
+        if self.vacancy_up != other.vacancy_up: return False
+        if self.vacancy != other.vacancy: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_mod_prop_vacancy {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("vacancy_down = ");
+                q.text("%#x" % self.vacancy_down)
+                q.text(","); q.breakable()
+                q.text("vacancy_up = ");
+                q.text("%#x" % self.vacancy_up)
+                q.text(","); q.breakable()
+                q.text("vacancy = ");
+                q.text("%#x" % self.vacancy)
+            q.breakable()
+        q.text('}')
+
+
+class table_stats_entry(loxi.OFObject):
+
+    def __init__(self, table_id=None, active_count=None, lookup_count=None, matched_count=None):
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if active_count != None:
+            self.active_count = active_count
+        else:
+            self.active_count = 0
+        if lookup_count != None:
+            self.lookup_count = lookup_count
+        else:
+            self.lookup_count = 0
+        if matched_count != None:
+            self.matched_count = matched_count
+        else:
+            self.matched_count = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append('\x00' * 3)
+        packed.append(struct.pack("!L", self.active_count))
+        packed.append(struct.pack("!Q", self.lookup_count))
+        packed.append(struct.pack("!Q", self.matched_count))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_stats_entry()
+        obj.table_id = reader.read("!B")[0]
+        reader.skip(3)
+        obj.active_count = reader.read("!L")[0]
+        obj.lookup_count = reader.read("!Q")[0]
+        obj.matched_count = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.table_id != other.table_id: return False
+        if self.active_count != other.active_count: return False
+        if self.lookup_count != other.lookup_count: return False
+        if self.matched_count != other.matched_count: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_stats_entry {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("active_count = ");
+                q.text("%#x" % self.active_count)
+                q.text(","); q.breakable()
+                q.text("lookup_count = ");
+                q.text("%#x" % self.lookup_count)
+                q.text(","); q.breakable()
+                q.text("matched_count = ");
+                q.text("%#x" % self.matched_count)
+            q.breakable()
+        q.text('}')
+
+
+class uint32(loxi.OFObject):
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = uint32()
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("uint32 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+
+class uint64(loxi.OFObject):
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!Q", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = uint64()
+        obj.value = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("uint64 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+
+class uint8(loxi.OFObject):
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = uint8()
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("uint8 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+
+
+match = match_v3
diff --git a/Fabric/Utilities/src/python/loxi/of14/const.py b/Fabric/Utilities/src/python/loxi/of14/const.py
new file mode 100644
index 0000000..93fd169
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of14/const.py
@@ -0,0 +1,1514 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template const.py
+# Do not modify
+
+OFP_VERSION = 5
+
+# Identifiers from group macro_definitions
+OFP_MAX_TABLE_NAME_LEN = 32
+OFP_MAX_PORT_NAME_LEN = 16
+OFP_TCP_PORT = 6653
+OFP_SSL_PORT = 6653
+OFP_ETH_ALEN = 6
+OFP_DEFAULT_MISS_SEND_LEN = 128
+OFP_VLAN_NONE = 0
+OFP_FLOW_PERMANENT = 0
+OFP_DEFAULT_PRIORITY = 32768
+OFP_NO_BUFFER = 4294967295
+DESC_STR_LEN = 256
+SERIAL_NUM_LEN = 32
+OFPQ_ALL = 4294967295
+OFPQ_MAX_RATE_UNCFG = 65535
+OFPQ_MIN_RATE_UNCFG = 65535
+
+# Identifiers from group of_bsn_lacp_convergence_status
+LACP_SUCCESS = 0
+LACP_TIMEDOUT = 1
+LACP_OUT_OF_SYNC = 2
+
+of_bsn_lacp_convergence_status_map = {
+    0: 'LACP_SUCCESS',
+    1: 'LACP_TIMEDOUT',
+    2: 'LACP_OUT_OF_SYNC',
+}
+
+# Identifiers from group of_bsn_pdu_slot_num
+BSN_PDU_SLOT_NUM_ANY = 255
+
+of_bsn_pdu_slot_num_map = {
+    255: 'BSN_PDU_SLOT_NUM_ANY',
+}
+
+# Identifiers from group of_bsn_vlan_counter
+OFP_BSN_VLAN_COUNTER_RX_BYTES = 0
+OFP_BSN_VLAN_COUNTER_RX_PACKETS = 1
+OFP_BSN_VLAN_COUNTER_TX_BYTES = 2
+OFP_BSN_VLAN_COUNTER_TX_PACKETS = 3
+
+of_bsn_vlan_counter_map = {
+    0: 'OFP_BSN_VLAN_COUNTER_RX_BYTES',
+    1: 'OFP_BSN_VLAN_COUNTER_RX_PACKETS',
+    2: 'OFP_BSN_VLAN_COUNTER_TX_BYTES',
+    3: 'OFP_BSN_VLAN_COUNTER_TX_PACKETS',
+}
+
+# Identifiers from group of_bsn_vrf_counter
+OFP_BSN_VRF_COUNTER_BYTES = 0
+OFP_BSN_VRF_COUNTER_PACKETS = 1
+
+of_bsn_vrf_counter_map = {
+    0: 'OFP_BSN_VRF_COUNTER_BYTES',
+    1: 'OFP_BSN_VRF_COUNTER_PACKETS',
+}
+
+# Identifiers from group ofp_action_type
+OFPAT_OUTPUT = 0
+OFPAT_COPY_TTL_OUT = 11
+OFPAT_COPY_TTL_IN = 12
+OFPAT_SET_MPLS_TTL = 15
+OFPAT_DEC_MPLS_TTL = 16
+OFPAT_PUSH_VLAN = 17
+OFPAT_POP_VLAN = 18
+OFPAT_PUSH_MPLS = 19
+OFPAT_POP_MPLS = 20
+OFPAT_SET_QUEUE = 21
+OFPAT_GROUP = 22
+OFPAT_SET_NW_TTL = 23
+OFPAT_DEC_NW_TTL = 24
+OFPAT_SET_FIELD = 25
+OFPAT_PUSH_PBB = 26
+OFPAT_POP_PBB = 27
+OFPAT_EXPERIMENTER = 65535
+
+ofp_action_type_map = {
+    0: 'OFPAT_OUTPUT',
+    11: 'OFPAT_COPY_TTL_OUT',
+    12: 'OFPAT_COPY_TTL_IN',
+    15: 'OFPAT_SET_MPLS_TTL',
+    16: 'OFPAT_DEC_MPLS_TTL',
+    17: 'OFPAT_PUSH_VLAN',
+    18: 'OFPAT_POP_VLAN',
+    19: 'OFPAT_PUSH_MPLS',
+    20: 'OFPAT_POP_MPLS',
+    21: 'OFPAT_SET_QUEUE',
+    22: 'OFPAT_GROUP',
+    23: 'OFPAT_SET_NW_TTL',
+    24: 'OFPAT_DEC_NW_TTL',
+    25: 'OFPAT_SET_FIELD',
+    26: 'OFPAT_PUSH_PBB',
+    27: 'OFPAT_POP_PBB',
+    65535: 'OFPAT_EXPERIMENTER',
+}
+
+# Identifiers from group ofp_async_config_failed_code
+OFPACFC_INVALID = 0
+OFPACFC_UNSUPPORTED = 1
+OFPACFC_EPERM = 2
+
+ofp_async_config_failed_code_map = {
+    0: 'OFPACFC_INVALID',
+    1: 'OFPACFC_UNSUPPORTED',
+    2: 'OFPACFC_EPERM',
+}
+
+# Identifiers from group ofp_bad_action_code
+OFPBAC_BAD_TYPE = 0
+OFPBAC_BAD_LEN = 1
+OFPBAC_BAD_EXPERIMENTER = 2
+OFPBAC_BAD_EXPERIMENTER_TYPE = 3
+OFPBAC_BAD_OUT_PORT = 4
+OFPBAC_BAD_ARGUMENT = 5
+OFPBAC_EPERM = 6
+OFPBAC_TOO_MANY = 7
+OFPBAC_BAD_QUEUE = 8
+OFPBAC_BAD_OUT_GROUP = 9
+OFPBAC_MATCH_INCONSISTENT = 10
+OFPBAC_UNSUPPORTED_ORDER = 11
+OFPBAC_BAD_TAG = 12
+OFPBAC_BAD_SET_TYPE = 13
+OFPBAC_BAD_SET_LEN = 14
+OFPBAC_BAD_SET_ARGUMENT = 15
+
+ofp_bad_action_code_map = {
+    0: 'OFPBAC_BAD_TYPE',
+    1: 'OFPBAC_BAD_LEN',
+    2: 'OFPBAC_BAD_EXPERIMENTER',
+    3: 'OFPBAC_BAD_EXPERIMENTER_TYPE',
+    4: 'OFPBAC_BAD_OUT_PORT',
+    5: 'OFPBAC_BAD_ARGUMENT',
+    6: 'OFPBAC_EPERM',
+    7: 'OFPBAC_TOO_MANY',
+    8: 'OFPBAC_BAD_QUEUE',
+    9: 'OFPBAC_BAD_OUT_GROUP',
+    10: 'OFPBAC_MATCH_INCONSISTENT',
+    11: 'OFPBAC_UNSUPPORTED_ORDER',
+    12: 'OFPBAC_BAD_TAG',
+    13: 'OFPBAC_BAD_SET_TYPE',
+    14: 'OFPBAC_BAD_SET_LEN',
+    15: 'OFPBAC_BAD_SET_ARGUMENT',
+}
+
+# Identifiers from group ofp_bad_instruction_code
+OFPBIC_UNKNOWN_INST = 0
+OFPBIC_UNSUP_INST = 1
+OFPBIC_BAD_TABLE_ID = 2
+OFPBIC_UNSUP_METADATA = 3
+OFPBIC_UNSUP_METADATA_MASK = 4
+OFPBIC_BAD_EXPERIMENTER = 5
+OFPBIC_BAD_EXPERIMENTER_TYPE = 6
+OFPBIC_BAD_LEN = 7
+OFPBIC_EPERM = 8
+OFPBIC_DUP_INST = 9
+
+ofp_bad_instruction_code_map = {
+    0: 'OFPBIC_UNKNOWN_INST',
+    1: 'OFPBIC_UNSUP_INST',
+    2: 'OFPBIC_BAD_TABLE_ID',
+    3: 'OFPBIC_UNSUP_METADATA',
+    4: 'OFPBIC_UNSUP_METADATA_MASK',
+    5: 'OFPBIC_BAD_EXPERIMENTER',
+    6: 'OFPBIC_BAD_EXPERIMENTER_TYPE',
+    7: 'OFPBIC_BAD_LEN',
+    8: 'OFPBIC_EPERM',
+    9: 'OFPBIC_DUP_INST',
+}
+
+# Identifiers from group ofp_bad_match_code
+OFPBMC_BAD_TYPE = 0
+OFPBMC_BAD_LEN = 1
+OFPBMC_BAD_TAG = 2
+OFPBMC_BAD_DL_ADDR_MASK = 3
+OFPBMC_BAD_NW_ADDR_MASK = 4
+OFPBMC_BAD_WILDCARDS = 5
+OFPBMC_BAD_FIELD = 6
+OFPBMC_BAD_VALUE = 7
+OFPBMC_BAD_MASK = 8
+OFPBMC_BAD_PREREQ = 9
+OFPBMC_DUP_FIELD = 10
+OFPBMC_EPERM = 11
+
+ofp_bad_match_code_map = {
+    0: 'OFPBMC_BAD_TYPE',
+    1: 'OFPBMC_BAD_LEN',
+    2: 'OFPBMC_BAD_TAG',
+    3: 'OFPBMC_BAD_DL_ADDR_MASK',
+    4: 'OFPBMC_BAD_NW_ADDR_MASK',
+    5: 'OFPBMC_BAD_WILDCARDS',
+    6: 'OFPBMC_BAD_FIELD',
+    7: 'OFPBMC_BAD_VALUE',
+    8: 'OFPBMC_BAD_MASK',
+    9: 'OFPBMC_BAD_PREREQ',
+    10: 'OFPBMC_DUP_FIELD',
+    11: 'OFPBMC_EPERM',
+}
+
+# Identifiers from group ofp_bad_property_code
+OFPBPC_BAD_TYPE = 0
+OFPBPC_BAD_LEN = 1
+OFPBPC_BAD_VALUE = 2
+OFPBPC_TOO_MANY = 3
+OFPBPC_DUP_TYPE = 4
+OFPBPC_BAD_EXPERIMENTER = 5
+OFPBPC_BAD_EXP_TYPE = 6
+OFPBPC_BAD_EXP_VALUE = 7
+OFPBPC_EPERM = 8
+
+ofp_bad_property_code_map = {
+    0: 'OFPBPC_BAD_TYPE',
+    1: 'OFPBPC_BAD_LEN',
+    2: 'OFPBPC_BAD_VALUE',
+    3: 'OFPBPC_TOO_MANY',
+    4: 'OFPBPC_DUP_TYPE',
+    5: 'OFPBPC_BAD_EXPERIMENTER',
+    6: 'OFPBPC_BAD_EXP_TYPE',
+    7: 'OFPBPC_BAD_EXP_VALUE',
+    8: 'OFPBPC_EPERM',
+}
+
+# Identifiers from group ofp_bad_request_code
+OFPBRC_BAD_VERSION = 0
+OFPBRC_BAD_TYPE = 1
+OFPBRC_BAD_STAT = 2
+OFPBRC_BAD_EXPERIMENTER = 3
+OFPBRC_BAD_EXPERIMENTER_TYPE = 4
+OFPBRC_EPERM = 5
+OFPBRC_BAD_LEN = 6
+OFPBRC_BUFFER_EMPTY = 7
+OFPBRC_BUFFER_UNKNOWN = 8
+OFPBRC_BAD_TABLE_ID = 9
+OFPBRC_IS_SLAVE = 10
+OFPBRC_BAD_PORT = 11
+OFPBRC_BAD_PACKET = 12
+OFPBRC_MULTIPART_BUFFER_OVERFLOW = 13
+OFPBRC_MULTIPART_REQUEST_TIMEOUT = 14
+OFPBRC_MULTIPART_REPLY_TIMEOUT = 15
+
+ofp_bad_request_code_map = {
+    0: 'OFPBRC_BAD_VERSION',
+    1: 'OFPBRC_BAD_TYPE',
+    2: 'OFPBRC_BAD_STAT',
+    3: 'OFPBRC_BAD_EXPERIMENTER',
+    4: 'OFPBRC_BAD_EXPERIMENTER_TYPE',
+    5: 'OFPBRC_EPERM',
+    6: 'OFPBRC_BAD_LEN',
+    7: 'OFPBRC_BUFFER_EMPTY',
+    8: 'OFPBRC_BUFFER_UNKNOWN',
+    9: 'OFPBRC_BAD_TABLE_ID',
+    10: 'OFPBRC_IS_SLAVE',
+    11: 'OFPBRC_BAD_PORT',
+    12: 'OFPBRC_BAD_PACKET',
+    13: 'OFPBRC_MULTIPART_BUFFER_OVERFLOW',
+    14: 'OFPBRC_MULTIPART_REQUEST_TIMEOUT',
+    15: 'OFPBRC_MULTIPART_REPLY_TIMEOUT',
+}
+
+# Identifiers from group ofp_bsn_anchor
+OFP_BSN_ANCHOR_PACKET_START = 0
+OFP_BSN_ANCHOR_L3_HEADER_START = 1
+OFP_BSN_ANCHOR_L4_HEADER_START = 2
+OFP_BSN_ANCHOR_L4_PAYLOAD_START = 3
+
+ofp_bsn_anchor_map = {
+    0: 'OFP_BSN_ANCHOR_PACKET_START',
+    1: 'OFP_BSN_ANCHOR_L3_HEADER_START',
+    2: 'OFP_BSN_ANCHOR_L4_HEADER_START',
+    3: 'OFP_BSN_ANCHOR_L4_PAYLOAD_START',
+}
+
+# Identifiers from group ofp_bsn_controller_connection_state
+OFP_BSN_CONTROLLER_CONNECTION_STATE_DISCONNECTED = 0
+OFP_BSN_CONTROLLER_CONNECTION_STATE_CONNECTED = 1
+
+ofp_bsn_controller_connection_state_map = {
+    0: 'OFP_BSN_CONTROLLER_CONNECTION_STATE_DISCONNECTED',
+    1: 'OFP_BSN_CONTROLLER_CONNECTION_STATE_CONNECTED',
+}
+
+# Identifiers from group ofp_bsn_lacp_state
+OFP_BSN_LACP_STATE_ACTIVITY = 1
+OFP_BSN_LACP_STATE_TIMEOUT = 2
+OFP_BSN_LACP_STATE_AGGREGATION = 4
+OFP_BSN_LACP_STATE_SYNCHRONIZATION = 8
+OFP_BSN_LACP_STATE_COLLECTING = 16
+OFP_BSN_LACP_STATE_DISTRIBUTING = 32
+OFP_BSN_LACP_STATE_DEFAULTED = 64
+OFP_BSN_LACP_STATE_EXPIRED = 128
+
+ofp_bsn_lacp_state_map = {
+    1: 'OFP_BSN_LACP_STATE_ACTIVITY',
+    2: 'OFP_BSN_LACP_STATE_TIMEOUT',
+    4: 'OFP_BSN_LACP_STATE_AGGREGATION',
+    8: 'OFP_BSN_LACP_STATE_SYNCHRONIZATION',
+    16: 'OFP_BSN_LACP_STATE_COLLECTING',
+    32: 'OFP_BSN_LACP_STATE_DISTRIBUTING',
+    64: 'OFP_BSN_LACP_STATE_DEFAULTED',
+    128: 'OFP_BSN_LACP_STATE_EXPIRED',
+}
+
+# Identifiers from group ofp_bsn_loglevel
+OFP_BSN_LOGLEVEL_MSG = 0
+OFP_BSN_LOGLEVEL_ERROR = 1
+OFP_BSN_LOGLEVEL_WARN = 2
+OFP_BSN_LOGLEVEL_INFO = 3
+OFP_BSN_LOGLEVEL_VERBOSE = 4
+OFP_BSN_LOGLEVEL_TRACE = 5
+
+ofp_bsn_loglevel_map = {
+    0: 'OFP_BSN_LOGLEVEL_MSG',
+    1: 'OFP_BSN_LOGLEVEL_ERROR',
+    2: 'OFP_BSN_LOGLEVEL_WARN',
+    3: 'OFP_BSN_LOGLEVEL_INFO',
+    4: 'OFP_BSN_LOGLEVEL_VERBOSE',
+    5: 'OFP_BSN_LOGLEVEL_TRACE',
+}
+
+# Identifiers from group ofp_bsn_lua_upload_flags
+OFP_BSN_LUA_UPLOAD_MORE = 1
+OFP_BSN_LUA_UPLOAD_FORCE = 2
+
+ofp_bsn_lua_upload_flags_map = {
+    1: 'OFP_BSN_LUA_UPLOAD_MORE',
+    2: 'OFP_BSN_LUA_UPLOAD_FORCE',
+}
+
+# Identifiers from group ofp_bsn_pktin_flag
+OFP_BSN_PKTIN_FLAG_PDU = 1
+OFP_BSN_PKTIN_FLAG_NEW_HOST = 2
+OFP_BSN_PKTIN_FLAG_STATION_MOVE = 4
+OFP_BSN_PKTIN_FLAG_ARP = 8
+OFP_BSN_PKTIN_FLAG_DHCP = 16
+OFP_BSN_PKTIN_FLAG_L2_CPU = 32
+OFP_BSN_PKTIN_FLAG_DEBUG = 64
+OFP_BSN_PKTIN_FLAG_TTL_EXPIRED = 128
+OFP_BSN_PKTIN_FLAG_L3_MISS = 256
+OFP_BSN_PKTIN_FLAG_L3_CPU = 512
+OFP_BSN_PKTIN_FLAG_INGRESS_ACL = 1024
+OFP_BSN_PKTIN_FLAG_SFLOW = 2048
+OFP_BSN_PKTIN_FLAG_ARP_CACHE = 4096
+OFP_BSN_PKTIN_FLAG_ARP_TARGET = 8192
+
+ofp_bsn_pktin_flag_map = {
+    1: 'OFP_BSN_PKTIN_FLAG_PDU',
+    2: 'OFP_BSN_PKTIN_FLAG_NEW_HOST',
+    4: 'OFP_BSN_PKTIN_FLAG_STATION_MOVE',
+    8: 'OFP_BSN_PKTIN_FLAG_ARP',
+    16: 'OFP_BSN_PKTIN_FLAG_DHCP',
+    32: 'OFP_BSN_PKTIN_FLAG_L2_CPU',
+    64: 'OFP_BSN_PKTIN_FLAG_DEBUG',
+    128: 'OFP_BSN_PKTIN_FLAG_TTL_EXPIRED',
+    256: 'OFP_BSN_PKTIN_FLAG_L3_MISS',
+    512: 'OFP_BSN_PKTIN_FLAG_L3_CPU',
+    1024: 'OFP_BSN_PKTIN_FLAG_INGRESS_ACL',
+    2048: 'OFP_BSN_PKTIN_FLAG_SFLOW',
+    4096: 'OFP_BSN_PKTIN_FLAG_ARP_CACHE',
+    8192: 'OFP_BSN_PKTIN_FLAG_ARP_TARGET',
+}
+
+# Identifiers from group ofp_bsn_port_counter
+OFP_BSN_PORT_COUNTER_RX_BYTES = 0
+OFP_BSN_PORT_COUNTER_RX_PACKETS_UNICAST = 1
+OFP_BSN_PORT_COUNTER_RX_PACKETS_BROADCAST = 2
+OFP_BSN_PORT_COUNTER_RX_PACKETS_MULTICAST = 3
+OFP_BSN_PORT_COUNTER_RX_DROPPED = 4
+OFP_BSN_PORT_COUNTER_RX_ERRORS = 5
+OFP_BSN_PORT_COUNTER_TX_BYTES = 6
+OFP_BSN_PORT_COUNTER_TX_PACKETS_UNICAST = 7
+OFP_BSN_PORT_COUNTER_TX_PACKETS_BROADCAST = 8
+OFP_BSN_PORT_COUNTER_TX_PACKETS_MULTICAST = 9
+OFP_BSN_PORT_COUNTER_TX_DROPPED = 10
+OFP_BSN_PORT_COUNTER_TX_ERRORS = 11
+OFP_BSN_PORT_COUNTER_RX_RUNTS = 12
+OFP_BSN_PORT_COUNTER_RX_GIANTS = 13
+OFP_BSN_PORT_COUNTER_RX_CRC_ERRORS = 14
+OFP_BSN_PORT_COUNTER_RX_ALIGNMENT_ERRORS = 15
+OFP_BSN_PORT_COUNTER_RX_SYMBOL_ERRORS = 16
+OFP_BSN_PORT_COUNTER_RX_PAUSE_INPUT = 17
+OFP_BSN_PORT_COUNTER_TX_COLLISIONS = 18
+OFP_BSN_PORT_COUNTER_TX_LATE_COLLISIONS = 19
+OFP_BSN_PORT_COUNTER_TX_DEFERRED = 20
+OFP_BSN_PORT_COUNTER_TX_PAUSE_OUTPUT = 21
+OFP_BSN_PORT_COUNTER_RX_PACKETS = 22
+OFP_BSN_PORT_COUNTER_TX_PACKETS = 23
+OFP_BSN_PORT_COUNTER_RX_LENGTH_ERRORS = 24
+OFP_BSN_PORT_COUNTER_RX_OVERFLOW_ERRORS = 25
+OFP_BSN_PORT_COUNTER_TX_CARRIER_ERRORS = 26
+OFP_BSN_PORT_COUNTER_RX_PACKETS_BAD_VLAN = 27
+
+ofp_bsn_port_counter_map = {
+    0: 'OFP_BSN_PORT_COUNTER_RX_BYTES',
+    1: 'OFP_BSN_PORT_COUNTER_RX_PACKETS_UNICAST',
+    2: 'OFP_BSN_PORT_COUNTER_RX_PACKETS_BROADCAST',
+    3: 'OFP_BSN_PORT_COUNTER_RX_PACKETS_MULTICAST',
+    4: 'OFP_BSN_PORT_COUNTER_RX_DROPPED',
+    5: 'OFP_BSN_PORT_COUNTER_RX_ERRORS',
+    6: 'OFP_BSN_PORT_COUNTER_TX_BYTES',
+    7: 'OFP_BSN_PORT_COUNTER_TX_PACKETS_UNICAST',
+    8: 'OFP_BSN_PORT_COUNTER_TX_PACKETS_BROADCAST',
+    9: 'OFP_BSN_PORT_COUNTER_TX_PACKETS_MULTICAST',
+    10: 'OFP_BSN_PORT_COUNTER_TX_DROPPED',
+    11: 'OFP_BSN_PORT_COUNTER_TX_ERRORS',
+    12: 'OFP_BSN_PORT_COUNTER_RX_RUNTS',
+    13: 'OFP_BSN_PORT_COUNTER_RX_GIANTS',
+    14: 'OFP_BSN_PORT_COUNTER_RX_CRC_ERRORS',
+    15: 'OFP_BSN_PORT_COUNTER_RX_ALIGNMENT_ERRORS',
+    16: 'OFP_BSN_PORT_COUNTER_RX_SYMBOL_ERRORS',
+    17: 'OFP_BSN_PORT_COUNTER_RX_PAUSE_INPUT',
+    18: 'OFP_BSN_PORT_COUNTER_TX_COLLISIONS',
+    19: 'OFP_BSN_PORT_COUNTER_TX_LATE_COLLISIONS',
+    20: 'OFP_BSN_PORT_COUNTER_TX_DEFERRED',
+    21: 'OFP_BSN_PORT_COUNTER_TX_PAUSE_OUTPUT',
+    22: 'OFP_BSN_PORT_COUNTER_RX_PACKETS',
+    23: 'OFP_BSN_PORT_COUNTER_TX_PACKETS',
+    24: 'OFP_BSN_PORT_COUNTER_RX_LENGTH_ERRORS',
+    25: 'OFP_BSN_PORT_COUNTER_RX_OVERFLOW_ERRORS',
+    26: 'OFP_BSN_PORT_COUNTER_TX_CARRIER_ERRORS',
+    27: 'OFP_BSN_PORT_COUNTER_RX_PACKETS_BAD_VLAN',
+}
+
+# Identifiers from group ofp_bsn_tcp_flag
+OFP_BSN_TCP_FLAG_FIN = 1
+OFP_BSN_TCP_FLAG_SYN = 2
+OFP_BSN_TCP_FLAG_RST = 4
+OFP_BSN_TCP_FLAG_PSH = 8
+OFP_BSN_TCP_FLAG_ACK = 16
+OFP_BSN_TCP_FLAG_URG = 32
+OFP_BSN_TCP_FLAG_ECE = 64
+OFP_BSN_TCP_FLAG_CWR = 128
+OFP_BSN_TCP_FLAG_NS = 256
+
+ofp_bsn_tcp_flag_map = {
+    1: 'OFP_BSN_TCP_FLAG_FIN',
+    2: 'OFP_BSN_TCP_FLAG_SYN',
+    4: 'OFP_BSN_TCP_FLAG_RST',
+    8: 'OFP_BSN_TCP_FLAG_PSH',
+    16: 'OFP_BSN_TCP_FLAG_ACK',
+    32: 'OFP_BSN_TCP_FLAG_URG',
+    64: 'OFP_BSN_TCP_FLAG_ECE',
+    128: 'OFP_BSN_TCP_FLAG_CWR',
+    256: 'OFP_BSN_TCP_FLAG_NS',
+}
+
+# Identifiers from group ofp_bsn_udf_anchor
+OFP_BSN_UDF_ANCHOR_PACKET_START = 0
+OFP_BSN_UDF_ANCHOR_L3_HEADER_START = 1
+OFP_BSN_UDF_ANCHOR_L4_HEADER_START = 2
+
+ofp_bsn_udf_anchor_map = {
+    0: 'OFP_BSN_UDF_ANCHOR_PACKET_START',
+    1: 'OFP_BSN_UDF_ANCHOR_L3_HEADER_START',
+    2: 'OFP_BSN_UDF_ANCHOR_L4_HEADER_START',
+}
+
+# Identifiers from group ofp_bsn_vlan_counter_constants
+OFP_BSN_VLAN_ALL = 65535
+
+ofp_bsn_vlan_counter_constants_map = {
+    65535: 'OFP_BSN_VLAN_ALL',
+}
+
+# Identifiers from group ofp_bsn_vport_l2gre_flags
+OF_BSN_VPORT_L2GRE_LOCAL_MAC_IS_VALID = 1
+OF_BSN_VPORT_L2GRE_DSCP_ASSIGN = 2
+OF_BSN_VPORT_L2GRE_DSCP_COPY = 4
+OF_BSN_VPORT_L2GRE_LOOPBACK_IS_VALID = 8
+OF_BSN_VPORT_L2GRE_RATE_LIMIT_IS_VALID = 16
+
+ofp_bsn_vport_l2gre_flags_map = {
+    1: 'OF_BSN_VPORT_L2GRE_LOCAL_MAC_IS_VALID',
+    2: 'OF_BSN_VPORT_L2GRE_DSCP_ASSIGN',
+    4: 'OF_BSN_VPORT_L2GRE_DSCP_COPY',
+    8: 'OF_BSN_VPORT_L2GRE_LOOPBACK_IS_VALID',
+    16: 'OF_BSN_VPORT_L2GRE_RATE_LIMIT_IS_VALID',
+}
+
+# Identifiers from group ofp_bsn_vport_q_in_q_untagged
+OF_BSN_VPORT_Q_IN_Q_UNTAGGED = 65535
+
+ofp_bsn_vport_q_in_q_untagged_map = {
+    65535: 'OF_BSN_VPORT_Q_IN_Q_UNTAGGED',
+}
+
+# Identifiers from group ofp_bsn_vport_status
+OF_BSN_VPORT_STATUS_OK = 0
+OF_BSN_VPORT_STATUS_FAILED = 1
+
+ofp_bsn_vport_status_map = {
+    0: 'OF_BSN_VPORT_STATUS_OK',
+    1: 'OF_BSN_VPORT_STATUS_FAILED',
+}
+
+# Identifiers from group ofp_bsn_vrf_counter_constants
+OFP_BSN_VRF_ALL = 4294967295
+
+ofp_bsn_vrf_counter_constants_map = {
+    4294967295: 'OFP_BSN_VRF_ALL',
+}
+
+# Identifiers from group ofp_bundle_ctrl_type
+OFPBCT_OPEN_REQUEST = 0
+OFPBCT_OPEN_REPLY = 1
+OFPBCT_CLOSE_REQUEST = 2
+OFPBCT_CLOSE_REPLY = 3
+OFPBCT_COMMIT_REQUEST = 4
+OFPBCT_COMMIT_REPLY = 5
+OFPBCT_DISCARD_REQUEST = 6
+OFPBCT_DISCARD_REPLY = 7
+
+ofp_bundle_ctrl_type_map = {
+    0: 'OFPBCT_OPEN_REQUEST',
+    1: 'OFPBCT_OPEN_REPLY',
+    2: 'OFPBCT_CLOSE_REQUEST',
+    3: 'OFPBCT_CLOSE_REPLY',
+    4: 'OFPBCT_COMMIT_REQUEST',
+    5: 'OFPBCT_COMMIT_REPLY',
+    6: 'OFPBCT_DISCARD_REQUEST',
+    7: 'OFPBCT_DISCARD_REPLY',
+}
+
+# Identifiers from group ofp_bundle_failed_code
+OFPBFC_UNKNOWN = 0
+OFPBFC_EPERM = 1
+OFPBFC_BAD_ID = 2
+OFPBFC_BUNDLE_EXIST = 3
+OFPBFC_BUNDLE_CLOSED = 4
+OFPBFC_OUT_OF_BUNDLES = 5
+OFPBFC_BAD_TYPE = 6
+OFPBFC_BAD_FLAGS = 7
+OFPBFC_MSG_BAD_LEN = 8
+OFPBFC_MSG_BAD_XID = 9
+OFPBFC_MSG_UNSUP = 10
+OFPBFC_MSG_CONFLICT = 11
+OFPBFC_MSG_TOO_MANY = 12
+OFPBFC_MSG_FAILED = 13
+OFPBFC_TIMEOUT = 14
+OFPBFC_BUNDLE_IN_PROGRESS = 15
+
+ofp_bundle_failed_code_map = {
+    0: 'OFPBFC_UNKNOWN',
+    1: 'OFPBFC_EPERM',
+    2: 'OFPBFC_BAD_ID',
+    3: 'OFPBFC_BUNDLE_EXIST',
+    4: 'OFPBFC_BUNDLE_CLOSED',
+    5: 'OFPBFC_OUT_OF_BUNDLES',
+    6: 'OFPBFC_BAD_TYPE',
+    7: 'OFPBFC_BAD_FLAGS',
+    8: 'OFPBFC_MSG_BAD_LEN',
+    9: 'OFPBFC_MSG_BAD_XID',
+    10: 'OFPBFC_MSG_UNSUP',
+    11: 'OFPBFC_MSG_CONFLICT',
+    12: 'OFPBFC_MSG_TOO_MANY',
+    13: 'OFPBFC_MSG_FAILED',
+    14: 'OFPBFC_TIMEOUT',
+    15: 'OFPBFC_BUNDLE_IN_PROGRESS',
+}
+
+# Identifiers from group ofp_bundle_flags
+OFPBF_ATOMIC = 1
+OFPBF_ORDERED = 2
+
+ofp_bundle_flags_map = {
+    1: 'OFPBF_ATOMIC',
+    2: 'OFPBF_ORDERED',
+}
+
+# Identifiers from group ofp_capabilities
+OFPC_FLOW_STATS = 1
+OFPC_TABLE_STATS = 2
+OFPC_PORT_STATS = 4
+OFPC_GROUP_STATS = 8
+OFPC_IP_REASM = 32
+OFPC_QUEUE_STATS = 64
+OFPC_PORT_BLOCKED = 256
+
+ofp_capabilities_map = {
+    1: 'OFPC_FLOW_STATS',
+    2: 'OFPC_TABLE_STATS',
+    4: 'OFPC_PORT_STATS',
+    8: 'OFPC_GROUP_STATS',
+    32: 'OFPC_IP_REASM',
+    64: 'OFPC_QUEUE_STATS',
+    256: 'OFPC_PORT_BLOCKED',
+}
+
+# Identifiers from group ofp_config_flags
+OFPC_FRAG_NORMAL = 0
+OFPC_FRAG_DROP = 1
+OFPC_FRAG_REASM = 2
+OFPC_FRAG_MASK = 3
+
+ofp_config_flags_map = {
+    0: 'OFPC_FRAG_NORMAL',
+    1: 'OFPC_FRAG_DROP',
+    2: 'OFPC_FRAG_REASM',
+    3: 'OFPC_FRAG_MASK',
+}
+
+# Identifiers from group ofp_controller_max_len
+OFPCML_MAX = 65509
+OFPCML_NO_BUFFER = 65535
+
+ofp_controller_max_len_map = {
+    65509: 'OFPCML_MAX',
+    65535: 'OFPCML_NO_BUFFER',
+}
+
+# Identifiers from group ofp_controller_role
+OFPCR_ROLE_NOCHANGE = 0
+OFPCR_ROLE_EQUAL = 1
+OFPCR_ROLE_MASTER = 2
+OFPCR_ROLE_SLAVE = 3
+
+ofp_controller_role_map = {
+    0: 'OFPCR_ROLE_NOCHANGE',
+    1: 'OFPCR_ROLE_EQUAL',
+    2: 'OFPCR_ROLE_MASTER',
+    3: 'OFPCR_ROLE_SLAVE',
+}
+
+# Identifiers from group ofp_controller_role_reason
+OFPCRR_MASTER_REQUEST = 0
+OFPCRR_CONFIG = 1
+OFPCRR_EXPERIMENTER = 2
+
+ofp_controller_role_reason_map = {
+    0: 'OFPCRR_MASTER_REQUEST',
+    1: 'OFPCRR_CONFIG',
+    2: 'OFPCRR_EXPERIMENTER',
+}
+
+# Identifiers from group ofp_error_type
+OFPET_HELLO_FAILED = 0
+OFPET_BAD_REQUEST = 1
+OFPET_BAD_ACTION = 2
+OFPET_BAD_INSTRUCTION = 3
+OFPET_BAD_MATCH = 4
+OFPET_FLOW_MOD_FAILED = 5
+OFPET_GROUP_MOD_FAILED = 6
+OFPET_PORT_MOD_FAILED = 7
+OFPET_TABLE_MOD_FAILED = 8
+OFPET_QUEUE_OP_FAILED = 9
+OFPET_SWITCH_CONFIG_FAILED = 10
+OFPET_ROLE_REQUEST_FAILED = 11
+OFPET_METER_MOD_FAILED = 12
+OFPET_TABLE_FEATURES_FAILED = 13
+OFPET_BAD_PROPERTY = 14
+OFPET_ASYNC_CONFIG_FAILED = 15
+OFPET_FLOW_MONITOR_FAILED = 16
+OFPET_BUNDLE_FAILED = 17
+OFPET_EXPERIMENTER = 65535
+
+ofp_error_type_map = {
+    0: 'OFPET_HELLO_FAILED',
+    1: 'OFPET_BAD_REQUEST',
+    2: 'OFPET_BAD_ACTION',
+    3: 'OFPET_BAD_INSTRUCTION',
+    4: 'OFPET_BAD_MATCH',
+    5: 'OFPET_FLOW_MOD_FAILED',
+    6: 'OFPET_GROUP_MOD_FAILED',
+    7: 'OFPET_PORT_MOD_FAILED',
+    8: 'OFPET_TABLE_MOD_FAILED',
+    9: 'OFPET_QUEUE_OP_FAILED',
+    10: 'OFPET_SWITCH_CONFIG_FAILED',
+    11: 'OFPET_ROLE_REQUEST_FAILED',
+    12: 'OFPET_METER_MOD_FAILED',
+    13: 'OFPET_TABLE_FEATURES_FAILED',
+    14: 'OFPET_BAD_PROPERTY',
+    15: 'OFPET_ASYNC_CONFIG_FAILED',
+    16: 'OFPET_FLOW_MONITOR_FAILED',
+    17: 'OFPET_BUNDLE_FAILED',
+    65535: 'OFPET_EXPERIMENTER',
+}
+
+# Identifiers from group ofp_flow_mod_command
+OFPFC_ADD = 0
+OFPFC_MODIFY = 1
+OFPFC_MODIFY_STRICT = 2
+OFPFC_DELETE = 3
+OFPFC_DELETE_STRICT = 4
+
+ofp_flow_mod_command_map = {
+    0: 'OFPFC_ADD',
+    1: 'OFPFC_MODIFY',
+    2: 'OFPFC_MODIFY_STRICT',
+    3: 'OFPFC_DELETE',
+    4: 'OFPFC_DELETE_STRICT',
+}
+
+# Identifiers from group ofp_flow_mod_failed_code
+OFPFMFC_UNKNOWN = 0
+OFPFMFC_TABLE_FULL = 1
+OFPFMFC_BAD_TABLE_ID = 2
+OFPFMFC_OVERLAP = 3
+OFPFMFC_EPERM = 4
+OFPFMFC_BAD_TIMEOUT = 5
+OFPFMFC_BAD_COMMAND = 6
+OFPFMFC_BAD_FLAGS = 7
+OFPFMFC_CANT_SYNC = 8
+OFPFMFC_BAD_PRIORITY = 9
+
+ofp_flow_mod_failed_code_map = {
+    0: 'OFPFMFC_UNKNOWN',
+    1: 'OFPFMFC_TABLE_FULL',
+    2: 'OFPFMFC_BAD_TABLE_ID',
+    3: 'OFPFMFC_OVERLAP',
+    4: 'OFPFMFC_EPERM',
+    5: 'OFPFMFC_BAD_TIMEOUT',
+    6: 'OFPFMFC_BAD_COMMAND',
+    7: 'OFPFMFC_BAD_FLAGS',
+    8: 'OFPFMFC_CANT_SYNC',
+    9: 'OFPFMFC_BAD_PRIORITY',
+}
+
+# Identifiers from group ofp_flow_mod_flags
+OFPFF_SEND_FLOW_REM = 1
+OFPFF_CHECK_OVERLAP = 2
+OFPFF_RESET_COUNTS = 4
+OFPFF_NO_PKT_COUNTS = 8
+OFPFF_NO_BYT_COUNTS = 16
+OFPFF_BSN_SEND_IDLE = 128
+
+ofp_flow_mod_flags_map = {
+    1: 'OFPFF_SEND_FLOW_REM',
+    2: 'OFPFF_CHECK_OVERLAP',
+    4: 'OFPFF_RESET_COUNTS',
+    8: 'OFPFF_NO_PKT_COUNTS',
+    16: 'OFPFF_NO_BYT_COUNTS',
+    128: 'OFPFF_BSN_SEND_IDLE',
+}
+
+# Identifiers from group ofp_flow_monitor_failed_code
+OFPMOFC_UNKNOWN = 0
+OFPMOFC_MONITOR_EXISTS = 1
+OFPMOFC_INVALID_MONITOR = 2
+OFPMOFC_UNKNOWN_MONITOR = 3
+OFPMOFC_BAD_COMMAND = 4
+OFPMOFC_BAD_FLAGS = 5
+OFPMOFC_BAD_TABLE_ID = 6
+OFPMOFC_BAD_OUT = 7
+
+ofp_flow_monitor_failed_code_map = {
+    0: 'OFPMOFC_UNKNOWN',
+    1: 'OFPMOFC_MONITOR_EXISTS',
+    2: 'OFPMOFC_INVALID_MONITOR',
+    3: 'OFPMOFC_UNKNOWN_MONITOR',
+    4: 'OFPMOFC_BAD_COMMAND',
+    5: 'OFPMOFC_BAD_FLAGS',
+    6: 'OFPMOFC_BAD_TABLE_ID',
+    7: 'OFPMOFC_BAD_OUT',
+}
+
+# Identifiers from group ofp_flow_removed_reason
+OFPRR_IDLE_TIMEOUT = 0
+OFPRR_HARD_TIMEOUT = 1
+OFPRR_DELETE = 2
+OFPRR_GROUP_DELETE = 3
+OFPRR_METER_DELETE = 4
+OFPRR_EVICTION = 5
+
+ofp_flow_removed_reason_map = {
+    0: 'OFPRR_IDLE_TIMEOUT',
+    1: 'OFPRR_HARD_TIMEOUT',
+    2: 'OFPRR_DELETE',
+    3: 'OFPRR_GROUP_DELETE',
+    4: 'OFPRR_METER_DELETE',
+    5: 'OFPRR_EVICTION',
+}
+
+# Identifiers from group ofp_group
+OFPG_MAX = 4294967040
+OFPG_ALL = 4294967292
+OFPG_ANY = 4294967295
+
+ofp_group_map = {
+    4294967040: 'OFPG_MAX',
+    4294967292: 'OFPG_ALL',
+    4294967295: 'OFPG_ANY',
+}
+
+# Identifiers from group ofp_group_capabilities
+OFPGFC_SELECT_WEIGHT = 1
+OFPGFC_SELECT_LIVENESS = 2
+OFPGFC_CHAINING = 4
+OFPGFC_CHAINING_CHECKS = 8
+
+ofp_group_capabilities_map = {
+    1: 'OFPGFC_SELECT_WEIGHT',
+    2: 'OFPGFC_SELECT_LIVENESS',
+    4: 'OFPGFC_CHAINING',
+    8: 'OFPGFC_CHAINING_CHECKS',
+}
+
+# Identifiers from group ofp_group_mod_command
+OFPGC_ADD = 0
+OFPGC_MODIFY = 1
+OFPGC_DELETE = 2
+
+ofp_group_mod_command_map = {
+    0: 'OFPGC_ADD',
+    1: 'OFPGC_MODIFY',
+    2: 'OFPGC_DELETE',
+}
+
+# Identifiers from group ofp_group_mod_failed_code
+OFPGMFC_GROUP_EXISTS = 0
+OFPGMFC_INVALID_GROUP = 1
+OFPGMFC_WEIGHT_UNSUPPORTED = 2
+OFPGMFC_OUT_OF_GROUPS = 3
+OFPGMFC_OUT_OF_BUCKETS = 4
+OFPGMFC_CHAINING_UNSUPPORTED = 5
+OFPGMFC_WATCH_UNSUPPORTED = 6
+OFPGMFC_LOOP = 7
+OFPGMFC_UNKNOWN_GROUP = 8
+OFPGMFC_CHAINED_GROUP = 9
+OFPGMFC_BAD_TYPE = 10
+OFPGMFC_BAD_COMMAND = 11
+OFPGMFC_BAD_BUCKET = 12
+OFPGMFC_BAD_WATCH = 13
+OFPGMFC_EPERM = 14
+
+ofp_group_mod_failed_code_map = {
+    0: 'OFPGMFC_GROUP_EXISTS',
+    1: 'OFPGMFC_INVALID_GROUP',
+    2: 'OFPGMFC_WEIGHT_UNSUPPORTED',
+    3: 'OFPGMFC_OUT_OF_GROUPS',
+    4: 'OFPGMFC_OUT_OF_BUCKETS',
+    5: 'OFPGMFC_CHAINING_UNSUPPORTED',
+    6: 'OFPGMFC_WATCH_UNSUPPORTED',
+    7: 'OFPGMFC_LOOP',
+    8: 'OFPGMFC_UNKNOWN_GROUP',
+    9: 'OFPGMFC_CHAINED_GROUP',
+    10: 'OFPGMFC_BAD_TYPE',
+    11: 'OFPGMFC_BAD_COMMAND',
+    12: 'OFPGMFC_BAD_BUCKET',
+    13: 'OFPGMFC_BAD_WATCH',
+    14: 'OFPGMFC_EPERM',
+}
+
+# Identifiers from group ofp_group_type
+OFPGT_ALL = 0
+OFPGT_SELECT = 1
+OFPGT_INDIRECT = 2
+OFPGT_FF = 3
+
+ofp_group_type_map = {
+    0: 'OFPGT_ALL',
+    1: 'OFPGT_SELECT',
+    2: 'OFPGT_INDIRECT',
+    3: 'OFPGT_FF',
+}
+
+# Identifiers from group ofp_hello_elem_type
+OFPHET_VERSIONBITMAP = 1
+
+ofp_hello_elem_type_map = {
+    1: 'OFPHET_VERSIONBITMAP',
+}
+
+# Identifiers from group ofp_hello_failed_code
+OFPHFC_INCOMPATIBLE = 0
+OFPHFC_EPERM = 1
+
+ofp_hello_failed_code_map = {
+    0: 'OFPHFC_INCOMPATIBLE',
+    1: 'OFPHFC_EPERM',
+}
+
+# Identifiers from group ofp_instruction_type
+OFPIT_GOTO_TABLE = 1
+OFPIT_WRITE_METADATA = 2
+OFPIT_WRITE_ACTIONS = 3
+OFPIT_APPLY_ACTIONS = 4
+OFPIT_CLEAR_ACTIONS = 5
+OFPIT_METER = 6
+OFPIT_EXPERIMENTER = 65535
+
+ofp_instruction_type_map = {
+    1: 'OFPIT_GOTO_TABLE',
+    2: 'OFPIT_WRITE_METADATA',
+    3: 'OFPIT_WRITE_ACTIONS',
+    4: 'OFPIT_APPLY_ACTIONS',
+    5: 'OFPIT_CLEAR_ACTIONS',
+    6: 'OFPIT_METER',
+    65535: 'OFPIT_EXPERIMENTER',
+}
+
+# Identifiers from group ofp_ipv6exthdr_flags
+OFPIEH_NONEXT = 1
+OFPIEH_ESP = 2
+OFPIEH_AUTH = 4
+OFPIEH_DEST = 8
+OFPIEH_FRAG = 16
+OFPIEH_ROUTER = 32
+OFPIEH_HOP = 64
+OFPIEH_UNREP = 128
+OFPIEH_UNSEQ = 256
+
+ofp_ipv6exthdr_flags_map = {
+    1: 'OFPIEH_NONEXT',
+    2: 'OFPIEH_ESP',
+    4: 'OFPIEH_AUTH',
+    8: 'OFPIEH_DEST',
+    16: 'OFPIEH_FRAG',
+    32: 'OFPIEH_ROUTER',
+    64: 'OFPIEH_HOP',
+    128: 'OFPIEH_UNREP',
+    256: 'OFPIEH_UNSEQ',
+}
+
+# Identifiers from group ofp_match_type
+OFPMT_STANDARD = 0
+OFPMT_OXM = 1
+
+ofp_match_type_map = {
+    0: 'OFPMT_STANDARD',
+    1: 'OFPMT_OXM',
+}
+
+# Identifiers from group ofp_meter
+OFPM_MAX = 4294901760
+OFPM_SLOWPATH = 4294967293
+OFPM_CONTROLLER = 4294967294
+OFPM_ALL = 4294967295
+
+ofp_meter_map = {
+    4294901760: 'OFPM_MAX',
+    4294967293: 'OFPM_SLOWPATH',
+    4294967294: 'OFPM_CONTROLLER',
+    4294967295: 'OFPM_ALL',
+}
+
+# Identifiers from group ofp_meter_band_type
+OFPMBT_DROP = 1
+OFPMBT_DSCP_REMARK = 2
+OFPMBT_EXPERIMENTER = 65535
+
+ofp_meter_band_type_map = {
+    1: 'OFPMBT_DROP',
+    2: 'OFPMBT_DSCP_REMARK',
+    65535: 'OFPMBT_EXPERIMENTER',
+}
+
+# Identifiers from group ofp_meter_flags
+OFPMF_KBPS = 1
+OFPMF_PKTPS = 2
+OFPMF_BURST = 4
+OFPMF_STATS = 8
+
+ofp_meter_flags_map = {
+    1: 'OFPMF_KBPS',
+    2: 'OFPMF_PKTPS',
+    4: 'OFPMF_BURST',
+    8: 'OFPMF_STATS',
+}
+
+# Identifiers from group ofp_meter_mod_command
+OFPMC_ADD = 0
+OFPMC_MODIFY = 1
+OFPMC_DELETE = 2
+
+ofp_meter_mod_command_map = {
+    0: 'OFPMC_ADD',
+    1: 'OFPMC_MODIFY',
+    2: 'OFPMC_DELETE',
+}
+
+# Identifiers from group ofp_meter_mod_failed_code
+OFPMMFC_UNKNOWN = 0
+OFPMMFC_METER_EXISTS = 1
+OFPMMFC_INVALID_METER = 2
+OFPMMFC_UNKNOWN_METER = 3
+OFPMMFC_BAD_COMMAND = 4
+OFPMMFC_BAD_FLAGS = 5
+OFPMMFC_BAD_RATE = 6
+OFPMMFC_BAD_BURST = 7
+OFPMMFC_BAD_BAND = 8
+OFPMMFC_BAD_BAND_VALUE = 9
+OFPMMFC_OUT_OF_METERS = 10
+OFPMMFC_OUT_OF_BANDS = 11
+
+ofp_meter_mod_failed_code_map = {
+    0: 'OFPMMFC_UNKNOWN',
+    1: 'OFPMMFC_METER_EXISTS',
+    2: 'OFPMMFC_INVALID_METER',
+    3: 'OFPMMFC_UNKNOWN_METER',
+    4: 'OFPMMFC_BAD_COMMAND',
+    5: 'OFPMMFC_BAD_FLAGS',
+    6: 'OFPMMFC_BAD_RATE',
+    7: 'OFPMMFC_BAD_BURST',
+    8: 'OFPMMFC_BAD_BAND',
+    9: 'OFPMMFC_BAD_BAND_VALUE',
+    10: 'OFPMMFC_OUT_OF_METERS',
+    11: 'OFPMMFC_OUT_OF_BANDS',
+}
+
+# Identifiers from group ofp_optical_port_features
+OFPOPF_RX_TUNE = 1
+OFPOPF_TX_TUNE = 2
+OFPOPF_TX_PWR = 4
+OFPOPF_USE_FREQ = 8
+
+ofp_optical_port_features_map = {
+    1: 'OFPOPF_RX_TUNE',
+    2: 'OFPOPF_TX_TUNE',
+    4: 'OFPOPF_TX_PWR',
+    8: 'OFPOPF_USE_FREQ',
+}
+
+# Identifiers from group ofp_oxm_class
+OFPXMC_NXM_0 = 0
+OFPXMC_NXM_1 = 1
+OFPXMC_OPENFLOW_BASIC = 32768
+OFPXMC_EXPERIMENTER = 65535
+
+ofp_oxm_class_map = {
+    0: 'OFPXMC_NXM_0',
+    1: 'OFPXMC_NXM_1',
+    32768: 'OFPXMC_OPENFLOW_BASIC',
+    65535: 'OFPXMC_EXPERIMENTER',
+}
+
+# Identifiers from group ofp_packet_in_reason
+OFPR_NO_MATCH = 0
+OFPR_ACTION = 1
+OFPR_INVALID_TTL = 2
+OFPR_ACTION_SET = 3
+OFPR_GROUP = 4
+OFPR_PACKET_OUT = 5
+OFPR_BSN_NEW_HOST = 128
+OFPR_BSN_STATION_MOVE = 129
+OFPR_BSN_BAD_VLAN = 130
+OFPR_BSN_DESTINATION_LOOKUP_FAILURE = 131
+OFPR_BSN_NO_ROUTE = 132
+OFPR_BSN_ICMP_ECHO_REQUEST = 133
+OFPR_BSN_DEST_NETWORK_UNREACHABLE = 134
+OFPR_BSN_DEST_HOST_UNREACHABLE = 135
+OFPR_BSN_DEST_PORT_UNREACHABLE = 136
+OFPR_BSN_FRAGMENTATION_REQUIRED = 137
+OFPR_BSN_ARP = 139
+OFPR_BSN_DHCP = 140
+OFPR_BSN_DEBUG = 141
+OFPR_BSN_PACKET_OF_DEATH = 142
+
+ofp_packet_in_reason_map = {
+    0: 'OFPR_NO_MATCH',
+    1: 'OFPR_ACTION',
+    2: 'OFPR_INVALID_TTL',
+    3: 'OFPR_ACTION_SET',
+    4: 'OFPR_GROUP',
+    5: 'OFPR_PACKET_OUT',
+    128: 'OFPR_BSN_NEW_HOST',
+    129: 'OFPR_BSN_STATION_MOVE',
+    130: 'OFPR_BSN_BAD_VLAN',
+    131: 'OFPR_BSN_DESTINATION_LOOKUP_FAILURE',
+    132: 'OFPR_BSN_NO_ROUTE',
+    133: 'OFPR_BSN_ICMP_ECHO_REQUEST',
+    134: 'OFPR_BSN_DEST_NETWORK_UNREACHABLE',
+    135: 'OFPR_BSN_DEST_HOST_UNREACHABLE',
+    136: 'OFPR_BSN_DEST_PORT_UNREACHABLE',
+    137: 'OFPR_BSN_FRAGMENTATION_REQUIRED',
+    139: 'OFPR_BSN_ARP',
+    140: 'OFPR_BSN_DHCP',
+    141: 'OFPR_BSN_DEBUG',
+    142: 'OFPR_BSN_PACKET_OF_DEATH',
+}
+
+# Identifiers from group ofp_port
+OFPP_MAX = 4294967040
+OFPP_IN_PORT = 4294967288
+OFPP_TABLE = 4294967289
+OFPP_NORMAL = 4294967290
+OFPP_FLOOD = 4294967291
+OFPP_ALL = 4294967292
+OFPP_CONTROLLER = 4294967293
+OFPP_LOCAL = 4294967294
+OFPP_ANY = 4294967295
+
+ofp_port_map = {
+    4294967040: 'OFPP_MAX',
+    4294967288: 'OFPP_IN_PORT',
+    4294967289: 'OFPP_TABLE',
+    4294967290: 'OFPP_NORMAL',
+    4294967291: 'OFPP_FLOOD',
+    4294967292: 'OFPP_ALL',
+    4294967293: 'OFPP_CONTROLLER',
+    4294967294: 'OFPP_LOCAL',
+    4294967295: 'OFPP_ANY',
+}
+
+# Identifiers from group ofp_port_config
+OFPPC_PORT_DOWN = 1
+OFPPC_NO_RECV = 4
+OFPPC_NO_FWD = 32
+OFPPC_NO_PACKET_IN = 64
+OFPPC_BSN_MIRROR_DEST = 2147483648
+
+ofp_port_config_map = {
+    1: 'OFPPC_PORT_DOWN',
+    4: 'OFPPC_NO_RECV',
+    32: 'OFPPC_NO_FWD',
+    64: 'OFPPC_NO_PACKET_IN',
+    2147483648: 'OFPPC_BSN_MIRROR_DEST',
+}
+
+# Identifiers from group ofp_port_features
+OFPPF_10MB_HD = 1
+OFPPF_10MB_FD = 2
+OFPPF_100MB_HD = 4
+OFPPF_100MB_FD = 8
+OFPPF_1GB_HD = 16
+OFPPF_1GB_FD = 32
+OFPPF_10GB_FD = 64
+OFPPF_40GB_FD = 128
+OFPPF_100GB_FD = 256
+OFPPF_1TB_FD = 512
+OFPPF_OTHER = 1024
+OFPPF_COPPER = 2048
+OFPPF_FIBER = 4096
+OFPPF_AUTONEG = 8192
+OFPPF_PAUSE = 16384
+OFPPF_PAUSE_ASYM = 32768
+OFPPF_BSN_BREAKOUT_CAPABLE = 2147483648
+
+ofp_port_features_map = {
+    1: 'OFPPF_10MB_HD',
+    2: 'OFPPF_10MB_FD',
+    4: 'OFPPF_100MB_HD',
+    8: 'OFPPF_100MB_FD',
+    16: 'OFPPF_1GB_HD',
+    32: 'OFPPF_1GB_FD',
+    64: 'OFPPF_10GB_FD',
+    128: 'OFPPF_40GB_FD',
+    256: 'OFPPF_100GB_FD',
+    512: 'OFPPF_1TB_FD',
+    1024: 'OFPPF_OTHER',
+    2048: 'OFPPF_COPPER',
+    4096: 'OFPPF_FIBER',
+    8192: 'OFPPF_AUTONEG',
+    16384: 'OFPPF_PAUSE',
+    32768: 'OFPPF_PAUSE_ASYM',
+    2147483648: 'OFPPF_BSN_BREAKOUT_CAPABLE',
+}
+
+# Identifiers from group ofp_port_mod_failed_code
+OFPPMFC_BAD_PORT = 0
+OFPPMFC_BAD_HW_ADDR = 1
+OFPPMFC_BAD_CONFIG = 2
+OFPPMFC_BAD_ADVERTISE = 3
+OFPPMFC_EPERM = 4
+
+ofp_port_mod_failed_code_map = {
+    0: 'OFPPMFC_BAD_PORT',
+    1: 'OFPPMFC_BAD_HW_ADDR',
+    2: 'OFPPMFC_BAD_CONFIG',
+    3: 'OFPPMFC_BAD_ADVERTISE',
+    4: 'OFPPMFC_EPERM',
+}
+
+# Identifiers from group ofp_port_reason
+OFPPR_ADD = 0
+OFPPR_DELETE = 1
+OFPPR_MODIFY = 2
+
+ofp_port_reason_map = {
+    0: 'OFPPR_ADD',
+    1: 'OFPPR_DELETE',
+    2: 'OFPPR_MODIFY',
+}
+
+# Identifiers from group ofp_port_state
+OFPPS_LINK_DOWN = 1
+OFPPS_BLOCKED = 2
+OFPPS_LIVE = 4
+
+ofp_port_state_map = {
+    1: 'OFPPS_LINK_DOWN',
+    2: 'OFPPS_BLOCKED',
+    4: 'OFPPS_LIVE',
+}
+
+# Identifiers from group ofp_port_stats_optical_flags
+OFPOSF_RX_TUNE = 1
+OFPOSF_TX_TUNE = 2
+OFPOSF_TX_PWR = 4
+OFPOSF_RX_PWR = 16
+OFPOSF_TX_BIAS = 32
+OFPOSF_TX_TEMP = 64
+
+ofp_port_stats_optical_flags_map = {
+    1: 'OFPOSF_RX_TUNE',
+    2: 'OFPOSF_TX_TUNE',
+    4: 'OFPOSF_TX_PWR',
+    16: 'OFPOSF_RX_PWR',
+    32: 'OFPOSF_TX_BIAS',
+    64: 'OFPOSF_TX_TEMP',
+}
+
+# Identifiers from group ofp_port_stats_prop_type
+OFPPSPT_ETHERNET = 0
+OFPPSPT_OPTICAL = 1
+OFPPSPT_EXPERIMENTER = 65535
+
+ofp_port_stats_prop_type_map = {
+    0: 'OFPPSPT_ETHERNET',
+    1: 'OFPPSPT_OPTICAL',
+    65535: 'OFPPSPT_EXPERIMENTER',
+}
+
+# Identifiers from group ofp_queue_op_failed_code
+OFPQOFC_BAD_PORT = 0
+OFPQOFC_BAD_QUEUE = 1
+OFPQOFC_EPERM = 2
+
+ofp_queue_op_failed_code_map = {
+    0: 'OFPQOFC_BAD_PORT',
+    1: 'OFPQOFC_BAD_QUEUE',
+    2: 'OFPQOFC_EPERM',
+}
+
+# Identifiers from group ofp_requestforward_reason
+OFPRFR_GROUP_MOD = 0
+OFPRFR_METER_MOD = 1
+
+ofp_requestforward_reason_map = {
+    0: 'OFPRFR_GROUP_MOD',
+    1: 'OFPRFR_METER_MOD',
+}
+
+# Identifiers from group ofp_role_request_failed_code
+OFPRRFC_STALE = 0
+OFPRRFC_UNSUP = 1
+OFPRRFC_BAD_ROLE = 2
+
+ofp_role_request_failed_code_map = {
+    0: 'OFPRRFC_STALE',
+    1: 'OFPRRFC_UNSUP',
+    2: 'OFPRRFC_BAD_ROLE',
+}
+
+# Identifiers from group ofp_stats_reply_flags
+OFPSF_REPLY_MORE = 1
+
+ofp_stats_reply_flags_map = {
+    1: 'OFPSF_REPLY_MORE',
+}
+
+# Identifiers from group ofp_stats_request_flags
+OFPSF_REQ_MORE = 1
+
+ofp_stats_request_flags_map = {
+    1: 'OFPSF_REQ_MORE',
+}
+
+# Identifiers from group ofp_stats_type
+OFPST_DESC = 0
+OFPST_FLOW = 1
+OFPST_AGGREGATE = 2
+OFPST_TABLE = 3
+OFPST_PORT = 4
+OFPST_QUEUE = 5
+OFPST_GROUP = 6
+OFPST_GROUP_DESC = 7
+OFPST_GROUP_FEATURES = 8
+OFPST_METER = 9
+OFPST_METER_CONFIG = 10
+OFPST_METER_FEATURES = 11
+OFPST_TABLE_FEATURES = 12
+OFPST_PORT_DESC = 13
+OFPMP_TABLE_DESC = 14
+OFPMP_QUEUE_DESC = 15
+OFPMP_FLOW_MONITOR = 16
+OFPST_EXPERIMENTER = 65535
+
+ofp_stats_type_map = {
+    0: 'OFPST_DESC',
+    1: 'OFPST_FLOW',
+    2: 'OFPST_AGGREGATE',
+    3: 'OFPST_TABLE',
+    4: 'OFPST_PORT',
+    5: 'OFPST_QUEUE',
+    6: 'OFPST_GROUP',
+    7: 'OFPST_GROUP_DESC',
+    8: 'OFPST_GROUP_FEATURES',
+    9: 'OFPST_METER',
+    10: 'OFPST_METER_CONFIG',
+    11: 'OFPST_METER_FEATURES',
+    12: 'OFPST_TABLE_FEATURES',
+    13: 'OFPST_PORT_DESC',
+    14: 'OFPMP_TABLE_DESC',
+    15: 'OFPMP_QUEUE_DESC',
+    16: 'OFPMP_FLOW_MONITOR',
+    65535: 'OFPST_EXPERIMENTER',
+}
+
+# Identifiers from group ofp_switch_config_failed_code
+OFPSCFC_BAD_FLAGS = 0
+OFPSCFC_BAD_LEN = 1
+OFPSCFC_EPERM = 2
+
+ofp_switch_config_failed_code_map = {
+    0: 'OFPSCFC_BAD_FLAGS',
+    1: 'OFPSCFC_BAD_LEN',
+    2: 'OFPSCFC_EPERM',
+}
+
+# Identifiers from group ofp_table
+OFPTT_MAX = 254
+OFPTT_ALL = 255
+
+ofp_table_map = {
+    254: 'OFPTT_MAX',
+    255: 'OFPTT_ALL',
+}
+
+# Identifiers from group ofp_table_config
+OFPTC_DEPRECATED_MASK = 3
+OFPTC_EVICTION = 4
+OFPTC_VACANCY_EVENTS = 8
+
+ofp_table_config_map = {
+    3: 'OFPTC_DEPRECATED_MASK',
+    4: 'OFPTC_EVICTION',
+    8: 'OFPTC_VACANCY_EVENTS',
+}
+
+# Identifiers from group ofp_table_feature_prop_type
+OFPTFPT_INSTRUCTIONS = 0
+OFPTFPT_INSTRUCTIONS_MISS = 1
+OFPTFPT_NEXT_TABLES = 2
+OFPTFPT_NEXT_TABLES_MISS = 3
+OFPTFPT_WRITE_ACTIONS = 4
+OFPTFPT_WRITE_ACTIONS_MISS = 5
+OFPTFPT_APPLY_ACTIONS = 6
+OFPTFPT_APPLY_ACTIONS_MISS = 7
+OFPTFPT_MATCH = 8
+OFPTFPT_WILDCARDS = 10
+OFPTFPT_WRITE_SETFIELD = 12
+OFPTFPT_WRITE_SETFIELD_MISS = 13
+OFPTFPT_APPLY_SETFIELD = 14
+OFPTFPT_APPLY_SETFIELD_MISS = 15
+OFPTFPT_TABLE_SYNC_FROM = 16
+OFPTFPT_EXPERIMENTER = 65534
+OFPTFPT_EXPERIMENTER_MISS = 65535
+
+ofp_table_feature_prop_type_map = {
+    0: 'OFPTFPT_INSTRUCTIONS',
+    1: 'OFPTFPT_INSTRUCTIONS_MISS',
+    2: 'OFPTFPT_NEXT_TABLES',
+    3: 'OFPTFPT_NEXT_TABLES_MISS',
+    4: 'OFPTFPT_WRITE_ACTIONS',
+    5: 'OFPTFPT_WRITE_ACTIONS_MISS',
+    6: 'OFPTFPT_APPLY_ACTIONS',
+    7: 'OFPTFPT_APPLY_ACTIONS_MISS',
+    8: 'OFPTFPT_MATCH',
+    10: 'OFPTFPT_WILDCARDS',
+    12: 'OFPTFPT_WRITE_SETFIELD',
+    13: 'OFPTFPT_WRITE_SETFIELD_MISS',
+    14: 'OFPTFPT_APPLY_SETFIELD',
+    15: 'OFPTFPT_APPLY_SETFIELD_MISS',
+    16: 'OFPTFPT_TABLE_SYNC_FROM',
+    65534: 'OFPTFPT_EXPERIMENTER',
+    65535: 'OFPTFPT_EXPERIMENTER_MISS',
+}
+
+# Identifiers from group ofp_table_features_failed_code
+OFPTFFC_BAD_TABLE = 0
+OFPTFFC_BAD_METADATA = 1
+OFPTFFC_EPERM = 5
+
+ofp_table_features_failed_code_map = {
+    0: 'OFPTFFC_BAD_TABLE',
+    1: 'OFPTFFC_BAD_METADATA',
+    5: 'OFPTFFC_EPERM',
+}
+
+# Identifiers from group ofp_table_mod_failed_code
+OFPTMFC_BAD_TABLE = 0
+OFPTMFC_BAD_CONFIG = 1
+OFPTMFC_EPERM = 2
+
+ofp_table_mod_failed_code_map = {
+    0: 'OFPTMFC_BAD_TABLE',
+    1: 'OFPTMFC_BAD_CONFIG',
+    2: 'OFPTMFC_EPERM',
+}
+
+# Identifiers from group ofp_table_mod_prop_eviction_flag
+OFPTMPEF_OTHER = 1
+OFPTMPEF_IMPORTANCE = 2
+OFPTMPEF_LIFETIME = 4
+
+ofp_table_mod_prop_eviction_flag_map = {
+    1: 'OFPTMPEF_OTHER',
+    2: 'OFPTMPEF_IMPORTANCE',
+    4: 'OFPTMPEF_LIFETIME',
+}
+
+# Identifiers from group ofp_table_reason
+OFPTR_VACANCY_DOWN = 3
+OFPTR_VACANCY_UP = 4
+
+ofp_table_reason_map = {
+    3: 'OFPTR_VACANCY_DOWN',
+    4: 'OFPTR_VACANCY_UP',
+}
+
+# Identifiers from group ofp_type
+OFPT_HELLO = 0
+OFPT_ERROR = 1
+OFPT_ECHO_REQUEST = 2
+OFPT_ECHO_REPLY = 3
+OFPT_EXPERIMENTER = 4
+OFPT_FEATURES_REQUEST = 5
+OFPT_FEATURES_REPLY = 6
+OFPT_GET_CONFIG_REQUEST = 7
+OFPT_GET_CONFIG_REPLY = 8
+OFPT_SET_CONFIG = 9
+OFPT_PACKET_IN = 10
+OFPT_FLOW_REMOVED = 11
+OFPT_PORT_STATUS = 12
+OFPT_PACKET_OUT = 13
+OFPT_FLOW_MOD = 14
+OFPT_GROUP_MOD = 15
+OFPT_PORT_MOD = 16
+OFPT_TABLE_MOD = 17
+OFPT_STATS_REQUEST = 18
+OFPT_STATS_REPLY = 19
+OFPT_BARRIER_REQUEST = 20
+OFPT_BARRIER_REPLY = 21
+OFPT_ROLE_REQUEST = 24
+OFPT_ROLE_REPLY = 25
+OFPT_GET_ASYNC_REQUEST = 26
+OFPT_GET_ASYNC_REPLY = 27
+OFPT_SET_ASYNC = 28
+OFPT_METER_MOD = 29
+OFPT_ROLE_STATUS = 30
+OFPT_TABLE_STATUS = 31
+OFPT_REQUESTFORWARD = 32
+OFPT_BUNDLE_CONTROL = 33
+OFPT_BUNDLE_ADD_MESSAGE = 34
+
+ofp_type_map = {
+    0: 'OFPT_HELLO',
+    1: 'OFPT_ERROR',
+    2: 'OFPT_ECHO_REQUEST',
+    3: 'OFPT_ECHO_REPLY',
+    4: 'OFPT_EXPERIMENTER',
+    5: 'OFPT_FEATURES_REQUEST',
+    6: 'OFPT_FEATURES_REPLY',
+    7: 'OFPT_GET_CONFIG_REQUEST',
+    8: 'OFPT_GET_CONFIG_REPLY',
+    9: 'OFPT_SET_CONFIG',
+    10: 'OFPT_PACKET_IN',
+    11: 'OFPT_FLOW_REMOVED',
+    12: 'OFPT_PORT_STATUS',
+    13: 'OFPT_PACKET_OUT',
+    14: 'OFPT_FLOW_MOD',
+    15: 'OFPT_GROUP_MOD',
+    16: 'OFPT_PORT_MOD',
+    17: 'OFPT_TABLE_MOD',
+    18: 'OFPT_STATS_REQUEST',
+    19: 'OFPT_STATS_REPLY',
+    20: 'OFPT_BARRIER_REQUEST',
+    21: 'OFPT_BARRIER_REPLY',
+    24: 'OFPT_ROLE_REQUEST',
+    25: 'OFPT_ROLE_REPLY',
+    26: 'OFPT_GET_ASYNC_REQUEST',
+    27: 'OFPT_GET_ASYNC_REPLY',
+    28: 'OFPT_SET_ASYNC',
+    29: 'OFPT_METER_MOD',
+    30: 'OFPT_ROLE_STATUS',
+    31: 'OFPT_TABLE_STATUS',
+    32: 'OFPT_REQUESTFORWARD',
+    33: 'OFPT_BUNDLE_CONTROL',
+    34: 'OFPT_BUNDLE_ADD_MESSAGE',
+}
+
+# Identifiers from group ofp_vlan_id
+OFPVID_NONE = 0
+OFPVID_PRESENT = 4096
+
+ofp_vlan_id_map = {
+    0: 'OFPVID_NONE',
+    4096: 'OFPVID_PRESENT',
+}
+
diff --git a/Fabric/Utilities/src/python/loxi/of14/instruction.py b/Fabric/Utilities/src/python/loxi/of14/instruction.py
new file mode 100644
index 0000000..d478f71
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of14/instruction.py
@@ -0,0 +1,1123 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of14']
+
+class instruction(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = instruction.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = instruction()
+        obj.type = reader.read("!H")[0]
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("instruction {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class apply_actions(instruction):
+    type = 4
+
+    def __init__(self, actions=None):
+        if actions != None:
+            self.actions = actions
+        else:
+            self.actions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.actions))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = apply_actions()
+        _type = reader.read("!H")[0]
+        assert(_type == 4)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        obj.actions = loxi.generic_util.unpack_list(reader, ofp.action.action.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.actions != other.actions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("apply_actions {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("actions = ");
+                q.pp(self.actions)
+            q.breakable()
+        q.text('}')
+
+instruction.subtypes[4] = apply_actions
+
+class experimenter(instruction):
+    subtypes = {}
+
+    type = 65535
+
+    def __init__(self, experimenter=None, data=None):
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 4)
+        subclass = experimenter.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = experimenter()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.experimenter = reader.read("!L")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.experimenter != other.experimenter: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+instruction.subtypes[65535] = experimenter
+
+class bsn(experimenter):
+    subtypes = {}
+
+    type = 65535
+    experimenter = 6035143
+
+    def __init__(self, subtype=None):
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 8)
+        subclass = bsn.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = bsn()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        obj.subtype = reader.read("!L")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+experimenter.subtypes[6035143] = bsn
+
+class bsn_arp_offload(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 1
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_arp_offload()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 1)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_arp_offload {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[1] = bsn_arp_offload
+
+class bsn_auto_negotiation(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 11
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_auto_negotiation()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 11)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_auto_negotiation {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[11] = bsn_auto_negotiation
+
+class bsn_deny(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 5
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_deny()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 5)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_deny {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[5] = bsn_deny
+
+class bsn_dhcp_offload(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 2
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_dhcp_offload()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 2)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_dhcp_offload {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[2] = bsn_dhcp_offload
+
+class bsn_disable_l3(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 13
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_disable_l3()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 13)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_disable_l3 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[13] = bsn_disable_l3
+
+class bsn_disable_src_mac_check(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 0
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_disable_src_mac_check()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 0)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_disable_src_mac_check {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[0] = bsn_disable_src_mac_check
+
+class bsn_disable_vlan_counters(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 9
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_disable_vlan_counters()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 9)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_disable_vlan_counters {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[9] = bsn_disable_vlan_counters
+
+class bsn_internal_priority(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 12
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.value))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_internal_priority()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 12)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_internal_priority {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[12] = bsn_internal_priority
+
+class bsn_packet_of_death(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 6
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_packet_of_death()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 6)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_packet_of_death {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[6] = bsn_packet_of_death
+
+class bsn_permit(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 4
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_permit()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_permit {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[4] = bsn_permit
+
+class bsn_prioritize_pdus(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 7
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_prioritize_pdus()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 7)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_prioritize_pdus {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[7] = bsn_prioritize_pdus
+
+class bsn_require_vlan_xlate(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 8
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_require_vlan_xlate()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 8)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_require_vlan_xlate {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[8] = bsn_require_vlan_xlate
+
+class bsn_span_destination(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 10
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_span_destination()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 10)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_span_destination {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[10] = bsn_span_destination
+
+class clear_actions(instruction):
+    type = 5
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = clear_actions()
+        _type = reader.read("!H")[0]
+        assert(_type == 5)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("clear_actions {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+instruction.subtypes[5] = clear_actions
+
+class goto_table(instruction):
+    type = 1
+
+    def __init__(self, table_id=None):
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = goto_table()
+        _type = reader.read("!H")[0]
+        assert(_type == 1)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.table_id = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.table_id != other.table_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("goto_table {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+            q.breakable()
+        q.text('}')
+
+instruction.subtypes[1] = goto_table
+
+class meter(instruction):
+    type = 6
+
+    def __init__(self, meter_id=None):
+        if meter_id != None:
+            self.meter_id = meter_id
+        else:
+            self.meter_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.meter_id))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = meter()
+        _type = reader.read("!H")[0]
+        assert(_type == 6)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.meter_id = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.meter_id != other.meter_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("meter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("meter_id = ");
+                q.text("%#x" % self.meter_id)
+            q.breakable()
+        q.text('}')
+
+instruction.subtypes[6] = meter
+
+class write_actions(instruction):
+    type = 3
+
+    def __init__(self, actions=None):
+        if actions != None:
+            self.actions = actions
+        else:
+            self.actions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.actions))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = write_actions()
+        _type = reader.read("!H")[0]
+        assert(_type == 3)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        obj.actions = loxi.generic_util.unpack_list(reader, ofp.action.action.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.actions != other.actions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("write_actions {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("actions = ");
+                q.pp(self.actions)
+            q.breakable()
+        q.text('}')
+
+instruction.subtypes[3] = write_actions
+
+class write_metadata(instruction):
+    type = 2
+
+    def __init__(self, metadata=None, metadata_mask=None):
+        if metadata != None:
+            self.metadata = metadata
+        else:
+            self.metadata = 0
+        if metadata_mask != None:
+            self.metadata_mask = metadata_mask
+        else:
+            self.metadata_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!Q", self.metadata))
+        packed.append(struct.pack("!Q", self.metadata_mask))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = write_metadata()
+        _type = reader.read("!H")[0]
+        assert(_type == 2)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        reader.skip(4)
+        obj.metadata = reader.read("!Q")[0]
+        obj.metadata_mask = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.metadata != other.metadata: return False
+        if self.metadata_mask != other.metadata_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("write_metadata {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("metadata = ");
+                q.text("%#x" % self.metadata)
+                q.text(","); q.breakable()
+                q.text("metadata_mask = ");
+                q.text("%#x" % self.metadata_mask)
+            q.breakable()
+        q.text('}')
+
+instruction.subtypes[2] = write_metadata
+
+
diff --git a/Fabric/Utilities/src/python/loxi/of14/instruction_id.py b/Fabric/Utilities/src/python/loxi/of14/instruction_id.py
new file mode 100644
index 0000000..1e3184d
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of14/instruction_id.py
@@ -0,0 +1,1014 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of14']
+
+class instruction_id(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = instruction_id.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = instruction_id()
+        obj.type = reader.read("!H")[0]
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("instruction_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class apply_actions(instruction_id):
+    type = 4
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = apply_actions()
+        _type = reader.read("!H")[0]
+        assert(_type == 4)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("apply_actions {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+instruction_id.subtypes[4] = apply_actions
+
+class experimenter(instruction_id):
+    subtypes = {}
+
+    type = 65535
+
+    def __init__(self, experimenter=None):
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 4)
+        subclass = experimenter.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = experimenter()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.experimenter = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.experimenter != other.experimenter: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+instruction_id.subtypes[65535] = experimenter
+
+class bsn(experimenter):
+    subtypes = {}
+
+    type = 65535
+    experimenter = 6035143
+
+    def __init__(self, subtype=None):
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 8)
+        subclass = bsn.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = bsn()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        obj.subtype = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+experimenter.subtypes[6035143] = bsn
+
+class bsn_arp_offload(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 1
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_arp_offload()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 1)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_arp_offload {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[1] = bsn_arp_offload
+
+class bsn_auto_negotiation(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 11
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_auto_negotiation()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 11)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_auto_negotiation {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[11] = bsn_auto_negotiation
+
+class bsn_deny(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 5
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_deny()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 5)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_deny {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[5] = bsn_deny
+
+class bsn_dhcp_offload(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 2
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_dhcp_offload()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 2)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_dhcp_offload {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[2] = bsn_dhcp_offload
+
+class bsn_disable_l3(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 13
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_disable_l3()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 13)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_disable_l3 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[13] = bsn_disable_l3
+
+class bsn_disable_src_mac_check(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 0
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_disable_src_mac_check()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 0)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_disable_src_mac_check {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[0] = bsn_disable_src_mac_check
+
+class bsn_disable_vlan_counters(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 9
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_disable_vlan_counters()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 9)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_disable_vlan_counters {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[9] = bsn_disable_vlan_counters
+
+class bsn_internal_priority(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 12
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_internal_priority()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 12)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_internal_priority {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[12] = bsn_internal_priority
+
+class bsn_packet_of_death(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 6
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_packet_of_death()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 6)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_packet_of_death {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[6] = bsn_packet_of_death
+
+class bsn_permit(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 4
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_permit()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_permit {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[4] = bsn_permit
+
+class bsn_prioritize_pdus(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 7
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_prioritize_pdus()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 7)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_prioritize_pdus {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[7] = bsn_prioritize_pdus
+
+class bsn_require_vlan_xlate(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 8
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_require_vlan_xlate()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 8)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_require_vlan_xlate {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[8] = bsn_require_vlan_xlate
+
+class bsn_span_destination(bsn):
+    type = 65535
+    experimenter = 6035143
+    subtype = 10
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_span_destination()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 10)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_span_destination {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[10] = bsn_span_destination
+
+class clear_actions(instruction_id):
+    type = 5
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = clear_actions()
+        _type = reader.read("!H")[0]
+        assert(_type == 5)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("clear_actions {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+instruction_id.subtypes[5] = clear_actions
+
+class goto_table(instruction_id):
+    type = 1
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = goto_table()
+        _type = reader.read("!H")[0]
+        assert(_type == 1)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("goto_table {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+instruction_id.subtypes[1] = goto_table
+
+class meter(instruction_id):
+    type = 6
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = meter()
+        _type = reader.read("!H")[0]
+        assert(_type == 6)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("meter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+instruction_id.subtypes[6] = meter
+
+class write_actions(instruction_id):
+    type = 3
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = write_actions()
+        _type = reader.read("!H")[0]
+        assert(_type == 3)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("write_actions {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+instruction_id.subtypes[3] = write_actions
+
+class write_metadata(instruction_id):
+    type = 2
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = write_metadata()
+        _type = reader.read("!H")[0]
+        assert(_type == 2)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("write_metadata {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+instruction_id.subtypes[2] = write_metadata
+
+
diff --git a/Fabric/Utilities/src/python/loxi/of14/message.py b/Fabric/Utilities/src/python/loxi/of14/message.py
new file mode 100644
index 0000000..c285bb7
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of14/message.py
@@ -0,0 +1,16078 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of14']
+
+class message(loxi.OFObject):
+    subtypes = {}
+
+    version = 5
+
+    def __init__(self, type=None, xid=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('B', 1)
+        subclass = message.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = message()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        obj.type = reader.read("!B")[0]
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("message {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+
+class stats_reply(message):
+    subtypes = {}
+
+    version = 5
+    type = 19
+
+    def __init__(self, xid=None, stats_type=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if stats_type != None:
+            self.stats_type = stats_type
+        else:
+            self.stats_type = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 8)
+        subclass = stats_reply.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.stats_type = reader.read("!H")[0]
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.stats_type != other.stats_type: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[19] = stats_reply
+
+class aggregate_stats_reply(stats_reply):
+    version = 5
+    type = 19
+    stats_type = 2
+
+    def __init__(self, xid=None, flags=None, packet_count=None, byte_count=None, flow_count=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if packet_count != None:
+            self.packet_count = packet_count
+        else:
+            self.packet_count = 0
+        if byte_count != None:
+            self.byte_count = byte_count
+        else:
+            self.byte_count = 0
+        if flow_count != None:
+            self.flow_count = flow_count
+        else:
+            self.flow_count = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!Q", self.packet_count))
+        packed.append(struct.pack("!Q", self.byte_count))
+        packed.append(struct.pack("!L", self.flow_count))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = aggregate_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 2)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.packet_count = reader.read("!Q")[0]
+        obj.byte_count = reader.read("!Q")[0]
+        obj.flow_count = reader.read("!L")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.packet_count != other.packet_count: return False
+        if self.byte_count != other.byte_count: return False
+        if self.flow_count != other.flow_count: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("aggregate_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("packet_count = ");
+                q.text("%#x" % self.packet_count)
+                q.text(","); q.breakable()
+                q.text("byte_count = ");
+                q.text("%#x" % self.byte_count)
+                q.text(","); q.breakable()
+                q.text("flow_count = ");
+                q.text("%#x" % self.flow_count)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[2] = aggregate_stats_reply
+
+class stats_request(message):
+    subtypes = {}
+
+    version = 5
+    type = 18
+
+    def __init__(self, xid=None, stats_type=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if stats_type != None:
+            self.stats_type = stats_type
+        else:
+            self.stats_type = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 8)
+        subclass = stats_request.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.stats_type = reader.read("!H")[0]
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.stats_type != other.stats_type: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[18] = stats_request
+
+class aggregate_stats_request(stats_request):
+    version = 5
+    type = 18
+    stats_type = 2
+
+    def __init__(self, xid=None, flags=None, table_id=None, out_port=None, out_group=None, cookie=None, cookie_mask=None, match=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if out_group != None:
+            self.out_group = out_group
+        else:
+            self.out_group = 0
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if cookie_mask != None:
+            self.cookie_mask = cookie_mask
+        else:
+            self.cookie_mask = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append('\x00' * 3)
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!L", self.out_group))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.cookie_mask))
+        packed.append(self.match.pack())
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = aggregate_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 2)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.table_id = reader.read("!B")[0]
+        reader.skip(3)
+        obj.out_port = util.unpack_port_no(reader)
+        obj.out_group = reader.read("!L")[0]
+        reader.skip(4)
+        obj.cookie = reader.read("!Q")[0]
+        obj.cookie_mask = reader.read("!Q")[0]
+        obj.match = ofp.match.unpack(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.table_id != other.table_id: return False
+        if self.out_port != other.out_port: return False
+        if self.out_group != other.out_group: return False
+        if self.cookie != other.cookie: return False
+        if self.cookie_mask != other.cookie_mask: return False
+        if self.match != other.match: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("aggregate_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("out_group = ");
+                q.text("%#x" % self.out_group)
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("cookie_mask = ");
+                q.text("%#x" % self.cookie_mask)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[2] = aggregate_stats_request
+
+class error_msg(message):
+    subtypes = {}
+
+    version = 5
+    type = 1
+
+    def __init__(self, xid=None, err_type=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if err_type != None:
+            self.err_type = err_type
+        else:
+            self.err_type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 8)
+        subclass = error_msg.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.err_type = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.err_type != other.err_type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+message.subtypes[1] = error_msg
+
+class async_config_failed_error_msg(error_msg):
+    version = 5
+    type = 1
+    err_type = 15
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = async_config_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 15)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("async_config_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[15] = async_config_failed_error_msg
+
+class async_get_reply(message):
+    version = 5
+    type = 27
+
+    def __init__(self, xid=None, properties=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if properties != None:
+            self.properties = properties
+        else:
+            self.properties = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(loxi.generic_util.pack_list(self.properties))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = async_get_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 27)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.properties = loxi.generic_util.unpack_list(reader, ofp.async_config_prop.async_config_prop.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.properties != other.properties: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("async_get_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("properties = ");
+                q.pp(self.properties)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[27] = async_get_reply
+
+class async_get_request(message):
+    version = 5
+    type = 26
+
+    def __init__(self, xid=None, properties=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if properties != None:
+            self.properties = properties
+        else:
+            self.properties = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(loxi.generic_util.pack_list(self.properties))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = async_get_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 26)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.properties = loxi.generic_util.unpack_list(reader, ofp.async_config_prop.async_config_prop.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.properties != other.properties: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("async_get_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("properties = ");
+                q.pp(self.properties)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[26] = async_get_request
+
+class async_set(message):
+    version = 5
+    type = 28
+
+    def __init__(self, xid=None, properties=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if properties != None:
+            self.properties = properties
+        else:
+            self.properties = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(loxi.generic_util.pack_list(self.properties))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = async_set()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 28)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.properties = loxi.generic_util.unpack_list(reader, ofp.async_config_prop.async_config_prop.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.properties != other.properties: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("async_set {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("properties = ");
+                q.pp(self.properties)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[28] = async_set
+
+class bad_action_error_msg(error_msg):
+    version = 5
+    type = 1
+    err_type = 2
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bad_action_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 2)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bad_action_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[2] = bad_action_error_msg
+
+class bad_instruction_error_msg(error_msg):
+    version = 5
+    type = 1
+    err_type = 3
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bad_instruction_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 3)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bad_instruction_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[3] = bad_instruction_error_msg
+
+class bad_match_error_msg(error_msg):
+    version = 5
+    type = 1
+    err_type = 4
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bad_match_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 4)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bad_match_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[4] = bad_match_error_msg
+
+class bad_property_error_msg(error_msg):
+    version = 5
+    type = 1
+    err_type = 14
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bad_property_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 14)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bad_property_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[14] = bad_property_error_msg
+
+class bad_request_error_msg(error_msg):
+    version = 5
+    type = 1
+    err_type = 1
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bad_request_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 1)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bad_request_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[1] = bad_request_error_msg
+
+class barrier_reply(message):
+    version = 5
+    type = 21
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = barrier_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 21)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("barrier_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+message.subtypes[21] = barrier_reply
+
+class barrier_request(message):
+    version = 5
+    type = 20
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = barrier_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 20)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("barrier_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+message.subtypes[20] = barrier_request
+
+class experimenter(message):
+    subtypes = {}
+
+    version = 5
+    type = 4
+
+    def __init__(self, xid=None, experimenter=None, subtype=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 8)
+        subclass = experimenter.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = experimenter()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.experimenter = reader.read("!L")[0]
+        obj.subtype = reader.read("!L")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.experimenter != other.experimenter: return False
+        if self.subtype != other.subtype: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("subtype = ");
+                q.text("%#x" % self.subtype)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[4] = experimenter
+
+class bsn_header(experimenter):
+    subtypes = {}
+
+    version = 5
+    type = 4
+    experimenter = 6035143
+
+    def __init__(self, xid=None, subtype=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 12)
+        subclass = bsn_header.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = bsn_header()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        obj.subtype = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_header {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+experimenter.subtypes[6035143] = bsn_header
+
+class bsn_arp_idle(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 60
+
+    def __init__(self, xid=None, vlan_vid=None, ipv4_addr=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if vlan_vid != None:
+            self.vlan_vid = vlan_vid
+        else:
+            self.vlan_vid = 0
+        if ipv4_addr != None:
+            self.ipv4_addr = ipv4_addr
+        else:
+            self.ipv4_addr = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!H", self.vlan_vid))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!L", self.ipv4_addr))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_arp_idle()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 60)
+        obj.vlan_vid = reader.read("!H")[0]
+        reader.skip(2)
+        obj.ipv4_addr = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.vlan_vid != other.vlan_vid: return False
+        if self.ipv4_addr != other.ipv4_addr: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_arp_idle {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("vlan_vid = ");
+                q.text("%#x" % self.vlan_vid)
+                q.text(","); q.breakable()
+                q.text("ipv4_addr = ");
+                q.text(util.pretty_ipv4(self.ipv4_addr))
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[60] = bsn_arp_idle
+
+class bsn_bw_clear_data_reply(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 22
+
+    def __init__(self, xid=None, status=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.status))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_bw_clear_data_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 22)
+        obj.status = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.status != other.status: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_bw_clear_data_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[22] = bsn_bw_clear_data_reply
+
+class bsn_bw_clear_data_request(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 21
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_bw_clear_data_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 21)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_bw_clear_data_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[21] = bsn_bw_clear_data_request
+
+class bsn_bw_enable_get_reply(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 20
+
+    def __init__(self, xid=None, enabled=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if enabled != None:
+            self.enabled = enabled
+        else:
+            self.enabled = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.enabled))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_bw_enable_get_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 20)
+        obj.enabled = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.enabled != other.enabled: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_bw_enable_get_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("enabled = ");
+                q.text("%#x" % self.enabled)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[20] = bsn_bw_enable_get_reply
+
+class bsn_bw_enable_get_request(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 19
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_bw_enable_get_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 19)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_bw_enable_get_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[19] = bsn_bw_enable_get_request
+
+class bsn_bw_enable_set_reply(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 23
+
+    def __init__(self, xid=None, enable=None, status=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if enable != None:
+            self.enable = enable
+        else:
+            self.enable = 0
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.enable))
+        packed.append(struct.pack("!L", self.status))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_bw_enable_set_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 23)
+        obj.enable = reader.read("!L")[0]
+        obj.status = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.enable != other.enable: return False
+        if self.status != other.status: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_bw_enable_set_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("enable = ");
+                q.text("%#x" % self.enable)
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[23] = bsn_bw_enable_set_reply
+
+class bsn_bw_enable_set_request(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 18
+
+    def __init__(self, xid=None, enable=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if enable != None:
+            self.enable = enable
+        else:
+            self.enable = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.enable))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_bw_enable_set_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 18)
+        obj.enable = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.enable != other.enable: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_bw_enable_set_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("enable = ");
+                q.text("%#x" % self.enable)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[18] = bsn_bw_enable_set_request
+
+class bsn_controller_connections_reply(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 57
+
+    def __init__(self, xid=None, connections=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if connections != None:
+            self.connections = connections
+        else:
+            self.connections = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.connections))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_controller_connections_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 57)
+        obj.connections = loxi.generic_util.unpack_list(reader, ofp.common.bsn_controller_connection.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.connections != other.connections: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_controller_connections_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("connections = ");
+                q.pp(self.connections)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[57] = bsn_controller_connections_reply
+
+class bsn_controller_connections_request(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 56
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_controller_connections_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 56)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_controller_connections_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[56] = bsn_controller_connections_request
+
+class experimenter_stats_reply(stats_reply):
+    subtypes = {}
+
+    version = 5
+    type = 19
+    stats_type = 65535
+
+    def __init__(self, xid=None, flags=None, experimenter=None, subtype=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 16)
+        subclass = experimenter_stats_reply.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = experimenter_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.experimenter = reader.read("!L")[0]
+        obj.subtype = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.experimenter != other.experimenter: return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("subtype = ");
+                q.text("%#x" % self.subtype)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[65535] = experimenter_stats_reply
+
+class bsn_stats_reply(experimenter_stats_reply):
+    subtypes = {}
+
+    version = 5
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+
+    def __init__(self, xid=None, flags=None, subtype=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 20)
+        subclass = bsn_stats_reply.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = bsn_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        obj.subtype = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+experimenter_stats_reply.subtypes[6035143] = bsn_stats_reply
+
+class bsn_debug_counter_desc_stats_reply(bsn_stats_reply):
+    version = 5
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 13
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_debug_counter_desc_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 13)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.bsn_debug_counter_desc_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_debug_counter_desc_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_reply.subtypes[13] = bsn_debug_counter_desc_stats_reply
+
+class experimenter_stats_request(stats_request):
+    subtypes = {}
+
+    version = 5
+    type = 18
+    stats_type = 65535
+
+    def __init__(self, xid=None, flags=None, experimenter=None, subtype=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 16)
+        subclass = experimenter_stats_request.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = experimenter_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.experimenter = reader.read("!L")[0]
+        obj.subtype = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.experimenter != other.experimenter: return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("subtype = ");
+                q.text("%#x" % self.subtype)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[65535] = experimenter_stats_request
+
+class bsn_stats_request(experimenter_stats_request):
+    subtypes = {}
+
+    version = 5
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+
+    def __init__(self, xid=None, flags=None, subtype=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 20)
+        subclass = bsn_stats_request.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = bsn_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        obj.subtype = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+experimenter_stats_request.subtypes[6035143] = bsn_stats_request
+
+class bsn_debug_counter_desc_stats_request(bsn_stats_request):
+    version = 5
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 13
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_debug_counter_desc_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 13)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_debug_counter_desc_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_request.subtypes[13] = bsn_debug_counter_desc_stats_request
+
+class bsn_debug_counter_stats_reply(bsn_stats_reply):
+    version = 5
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 12
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_debug_counter_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 12)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.bsn_debug_counter_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_debug_counter_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_reply.subtypes[12] = bsn_debug_counter_stats_reply
+
+class bsn_debug_counter_stats_request(bsn_stats_request):
+    version = 5
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 12
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_debug_counter_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 12)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_debug_counter_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_request.subtypes[12] = bsn_debug_counter_stats_request
+
+class bsn_flow_checksum_bucket_stats_reply(bsn_stats_reply):
+    version = 5
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 10
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_flow_checksum_bucket_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 10)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.bsn_flow_checksum_bucket_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_flow_checksum_bucket_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_reply.subtypes[10] = bsn_flow_checksum_bucket_stats_reply
+
+class bsn_flow_checksum_bucket_stats_request(bsn_stats_request):
+    version = 5
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 10
+
+    def __init__(self, xid=None, flags=None, table_id=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!B", self.table_id))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_flow_checksum_bucket_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 10)
+        obj.table_id = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.table_id != other.table_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_flow_checksum_bucket_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_request.subtypes[10] = bsn_flow_checksum_bucket_stats_request
+
+class bsn_flow_idle(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 40
+
+    def __init__(self, xid=None, cookie=None, priority=None, table_id=None, match=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append('\x00' * 5)
+        packed.append(self.match.pack())
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_flow_idle()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 40)
+        obj.cookie = reader.read("!Q")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.table_id = reader.read("!B")[0]
+        reader.skip(5)
+        obj.match = ofp.match.unpack(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.cookie != other.cookie: return False
+        if self.priority != other.priority: return False
+        if self.table_id != other.table_id: return False
+        if self.match != other.match: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_flow_idle {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[40] = bsn_flow_idle
+
+class bsn_flow_idle_enable_get_reply(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 39
+
+    def __init__(self, xid=None, enabled=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if enabled != None:
+            self.enabled = enabled
+        else:
+            self.enabled = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.enabled))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_flow_idle_enable_get_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 39)
+        obj.enabled = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.enabled != other.enabled: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_flow_idle_enable_get_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("enabled = ");
+                q.text("%#x" % self.enabled)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[39] = bsn_flow_idle_enable_get_reply
+
+class bsn_flow_idle_enable_get_request(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 38
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_flow_idle_enable_get_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 38)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_flow_idle_enable_get_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[38] = bsn_flow_idle_enable_get_request
+
+class bsn_flow_idle_enable_set_reply(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 37
+
+    def __init__(self, xid=None, enable=None, status=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if enable != None:
+            self.enable = enable
+        else:
+            self.enable = 0
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.enable))
+        packed.append(struct.pack("!L", self.status))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_flow_idle_enable_set_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 37)
+        obj.enable = reader.read("!L")[0]
+        obj.status = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.enable != other.enable: return False
+        if self.status != other.status: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_flow_idle_enable_set_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("enable = ");
+                q.text("%#x" % self.enable)
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[37] = bsn_flow_idle_enable_set_reply
+
+class bsn_flow_idle_enable_set_request(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 36
+
+    def __init__(self, xid=None, enable=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if enable != None:
+            self.enable = enable
+        else:
+            self.enable = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.enable))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_flow_idle_enable_set_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 36)
+        obj.enable = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.enable != other.enable: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_flow_idle_enable_set_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("enable = ");
+                q.text("%#x" % self.enable)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[36] = bsn_flow_idle_enable_set_request
+
+class bsn_generic_async(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 68
+
+    def __init__(self, xid=None, name=None, tlvs=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if name != None:
+            self.name = name
+        else:
+            self.name = ""
+        if tlvs != None:
+            self.tlvs = tlvs
+        else:
+            self.tlvs = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!64s", self.name))
+        packed.append(loxi.generic_util.pack_list(self.tlvs))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_generic_async()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 68)
+        obj.name = reader.read("!64s")[0].rstrip("\x00")
+        obj.tlvs = loxi.generic_util.unpack_list(reader, ofp.bsn_tlv.bsn_tlv.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.name != other.name: return False
+        if self.tlvs != other.tlvs: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_generic_async {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("name = ");
+                q.pp(self.name)
+                q.text(","); q.breakable()
+                q.text("tlvs = ");
+                q.pp(self.tlvs)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[68] = bsn_generic_async
+
+class bsn_generic_stats_reply(bsn_stats_reply):
+    version = 5
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 16
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_generic_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 16)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.bsn_generic_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_generic_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_reply.subtypes[16] = bsn_generic_stats_reply
+
+class bsn_generic_stats_request(bsn_stats_request):
+    version = 5
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 16
+
+    def __init__(self, xid=None, flags=None, name=None, tlvs=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if name != None:
+            self.name = name
+        else:
+            self.name = ""
+        if tlvs != None:
+            self.tlvs = tlvs
+        else:
+            self.tlvs = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!64s", self.name))
+        packed.append(loxi.generic_util.pack_list(self.tlvs))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_generic_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 16)
+        obj.name = reader.read("!64s")[0].rstrip("\x00")
+        obj.tlvs = loxi.generic_util.unpack_list(reader, ofp.bsn_tlv.bsn_tlv.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.name != other.name: return False
+        if self.tlvs != other.tlvs: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_generic_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("name = ");
+                q.pp(self.name)
+                q.text(","); q.breakable()
+                q.text("tlvs = ");
+                q.pp(self.tlvs)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_request.subtypes[16] = bsn_generic_stats_request
+
+class bsn_gentable_bucket_stats_reply(bsn_stats_reply):
+    version = 5
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 5
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_bucket_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 5)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.bsn_gentable_bucket_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_bucket_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_reply.subtypes[5] = bsn_gentable_bucket_stats_reply
+
+class bsn_gentable_bucket_stats_request(bsn_stats_request):
+    version = 5
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 5
+
+    def __init__(self, xid=None, flags=None, table_id=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!H", self.table_id))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_bucket_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 5)
+        obj.table_id = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.table_id != other.table_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_bucket_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_request.subtypes[5] = bsn_gentable_bucket_stats_request
+
+class bsn_gentable_clear_reply(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 49
+
+    def __init__(self, xid=None, table_id=None, deleted_count=None, error_count=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if deleted_count != None:
+            self.deleted_count = deleted_count
+        else:
+            self.deleted_count = 0
+        if error_count != None:
+            self.error_count = error_count
+        else:
+            self.error_count = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!H", self.table_id))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!L", self.deleted_count))
+        packed.append(struct.pack("!L", self.error_count))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_clear_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 49)
+        obj.table_id = reader.read("!H")[0]
+        reader.skip(2)
+        obj.deleted_count = reader.read("!L")[0]
+        obj.error_count = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.table_id != other.table_id: return False
+        if self.deleted_count != other.deleted_count: return False
+        if self.error_count != other.error_count: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_clear_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("deleted_count = ");
+                q.text("%#x" % self.deleted_count)
+                q.text(","); q.breakable()
+                q.text("error_count = ");
+                q.text("%#x" % self.error_count)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[49] = bsn_gentable_clear_reply
+
+class bsn_gentable_clear_request(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 48
+
+    def __init__(self, xid=None, table_id=None, checksum=None, checksum_mask=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if checksum != None:
+            self.checksum = checksum
+        else:
+            self.checksum = 0
+        if checksum_mask != None:
+            self.checksum_mask = checksum_mask
+        else:
+            self.checksum_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!H", self.table_id))
+        packed.append('\x00' * 2)
+        packed.append(util.pack_checksum_128(self.checksum))
+        packed.append(util.pack_checksum_128(self.checksum_mask))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_clear_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 48)
+        obj.table_id = reader.read("!H")[0]
+        reader.skip(2)
+        obj.checksum = util.unpack_checksum_128(reader)
+        obj.checksum_mask = util.unpack_checksum_128(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.table_id != other.table_id: return False
+        if self.checksum != other.checksum: return False
+        if self.checksum_mask != other.checksum_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_clear_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("checksum = ");
+                q.pp(self.checksum)
+                q.text(","); q.breakable()
+                q.text("checksum_mask = ");
+                q.pp(self.checksum_mask)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[48] = bsn_gentable_clear_request
+
+class bsn_gentable_desc_stats_reply(bsn_stats_reply):
+    version = 5
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 4
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_desc_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.bsn_gentable_desc_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_desc_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_reply.subtypes[4] = bsn_gentable_desc_stats_reply
+
+class bsn_gentable_desc_stats_request(bsn_stats_request):
+    version = 5
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 4
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_desc_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_desc_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_request.subtypes[4] = bsn_gentable_desc_stats_request
+
+class bsn_gentable_entry_add(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 46
+
+    def __init__(self, xid=None, table_id=None, checksum=None, key=None, value=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if checksum != None:
+            self.checksum = checksum
+        else:
+            self.checksum = 0
+        if key != None:
+            self.key = key
+        else:
+            self.key = []
+        if value != None:
+            self.value = value
+        else:
+            self.value = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!H", self.table_id))
+        packed.append(struct.pack("!H", 0)) # placeholder for key_length at index 7
+        packed.append(util.pack_checksum_128(self.checksum))
+        packed.append(loxi.generic_util.pack_list(self.key))
+        packed[7] = struct.pack("!H", len(packed[-1]))
+        packed.append(loxi.generic_util.pack_list(self.value))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_entry_add()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 46)
+        obj.table_id = reader.read("!H")[0]
+        _key_length = reader.read("!H")[0]
+        obj.checksum = util.unpack_checksum_128(reader)
+        obj.key = loxi.generic_util.unpack_list(reader.slice(_key_length), ofp.bsn_tlv.bsn_tlv.unpack)
+        obj.value = loxi.generic_util.unpack_list(reader, ofp.bsn_tlv.bsn_tlv.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.table_id != other.table_id: return False
+        if self.checksum != other.checksum: return False
+        if self.key != other.key: return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_entry_add {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("checksum = ");
+                q.pp(self.checksum)
+                q.text(","); q.breakable()
+                q.text("key = ");
+                q.pp(self.key)
+                q.text(","); q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[46] = bsn_gentable_entry_add
+
+class bsn_gentable_entry_delete(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 47
+
+    def __init__(self, xid=None, table_id=None, key=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if key != None:
+            self.key = key
+        else:
+            self.key = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!H", self.table_id))
+        packed.append(loxi.generic_util.pack_list(self.key))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_entry_delete()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 47)
+        obj.table_id = reader.read("!H")[0]
+        obj.key = loxi.generic_util.unpack_list(reader, ofp.bsn_tlv.bsn_tlv.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.table_id != other.table_id: return False
+        if self.key != other.key: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_entry_delete {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("key = ");
+                q.pp(self.key)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[47] = bsn_gentable_entry_delete
+
+class bsn_gentable_entry_desc_stats_reply(bsn_stats_reply):
+    version = 5
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 2
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_entry_desc_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 2)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.bsn_gentable_entry_desc_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_entry_desc_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_reply.subtypes[2] = bsn_gentable_entry_desc_stats_reply
+
+class bsn_gentable_entry_desc_stats_request(bsn_stats_request):
+    version = 5
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 2
+
+    def __init__(self, xid=None, flags=None, table_id=None, checksum=None, checksum_mask=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if checksum != None:
+            self.checksum = checksum
+        else:
+            self.checksum = 0
+        if checksum_mask != None:
+            self.checksum_mask = checksum_mask
+        else:
+            self.checksum_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!H", self.table_id))
+        packed.append('\x00' * 2)
+        packed.append(util.pack_checksum_128(self.checksum))
+        packed.append(util.pack_checksum_128(self.checksum_mask))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_entry_desc_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 2)
+        obj.table_id = reader.read("!H")[0]
+        reader.skip(2)
+        obj.checksum = util.unpack_checksum_128(reader)
+        obj.checksum_mask = util.unpack_checksum_128(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.table_id != other.table_id: return False
+        if self.checksum != other.checksum: return False
+        if self.checksum_mask != other.checksum_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_entry_desc_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("checksum = ");
+                q.pp(self.checksum)
+                q.text(","); q.breakable()
+                q.text("checksum_mask = ");
+                q.pp(self.checksum_mask)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_request.subtypes[2] = bsn_gentable_entry_desc_stats_request
+
+class bsn_gentable_entry_stats_reply(bsn_stats_reply):
+    version = 5
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 3
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_entry_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 3)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.bsn_gentable_entry_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_entry_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_reply.subtypes[3] = bsn_gentable_entry_stats_reply
+
+class bsn_gentable_entry_stats_request(bsn_stats_request):
+    version = 5
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 3
+
+    def __init__(self, xid=None, flags=None, table_id=None, checksum=None, checksum_mask=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if checksum != None:
+            self.checksum = checksum
+        else:
+            self.checksum = 0
+        if checksum_mask != None:
+            self.checksum_mask = checksum_mask
+        else:
+            self.checksum_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!H", self.table_id))
+        packed.append('\x00' * 2)
+        packed.append(util.pack_checksum_128(self.checksum))
+        packed.append(util.pack_checksum_128(self.checksum_mask))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_entry_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 3)
+        obj.table_id = reader.read("!H")[0]
+        reader.skip(2)
+        obj.checksum = util.unpack_checksum_128(reader)
+        obj.checksum_mask = util.unpack_checksum_128(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.table_id != other.table_id: return False
+        if self.checksum != other.checksum: return False
+        if self.checksum_mask != other.checksum_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_entry_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("checksum = ");
+                q.pp(self.checksum)
+                q.text(","); q.breakable()
+                q.text("checksum_mask = ");
+                q.pp(self.checksum_mask)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_request.subtypes[3] = bsn_gentable_entry_stats_request
+
+class bsn_gentable_set_buckets_size(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 50
+
+    def __init__(self, xid=None, table_id=None, buckets_size=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if buckets_size != None:
+            self.buckets_size = buckets_size
+        else:
+            self.buckets_size = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!H", self.table_id))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!L", self.buckets_size))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_set_buckets_size()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 50)
+        obj.table_id = reader.read("!H")[0]
+        reader.skip(2)
+        obj.buckets_size = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.table_id != other.table_id: return False
+        if self.buckets_size != other.buckets_size: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_set_buckets_size {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("buckets_size = ");
+                q.text("%#x" % self.buckets_size)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[50] = bsn_gentable_set_buckets_size
+
+class bsn_gentable_stats_reply(bsn_stats_reply):
+    version = 5
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 7
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 7)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.bsn_gentable_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_reply.subtypes[7] = bsn_gentable_stats_reply
+
+class bsn_gentable_stats_request(bsn_stats_request):
+    version = 5
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 7
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_gentable_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 7)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_gentable_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_request.subtypes[7] = bsn_gentable_stats_request
+
+class bsn_get_interfaces_reply(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 10
+
+    def __init__(self, xid=None, interfaces=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if interfaces != None:
+            self.interfaces = interfaces
+        else:
+            self.interfaces = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.interfaces))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_get_interfaces_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 10)
+        obj.interfaces = loxi.generic_util.unpack_list(reader, ofp.common.bsn_interface.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.interfaces != other.interfaces: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_get_interfaces_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("interfaces = ");
+                q.pp(self.interfaces)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[10] = bsn_get_interfaces_reply
+
+class bsn_get_interfaces_request(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 9
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_get_interfaces_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 9)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_get_interfaces_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[9] = bsn_get_interfaces_request
+
+class bsn_get_mirroring_reply(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 5
+
+    def __init__(self, xid=None, report_mirror_ports=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if report_mirror_ports != None:
+            self.report_mirror_ports = report_mirror_ports
+        else:
+            self.report_mirror_ports = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!B", self.report_mirror_ports))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_get_mirroring_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 5)
+        obj.report_mirror_ports = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.report_mirror_ports != other.report_mirror_ports: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_get_mirroring_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("report_mirror_ports = ");
+                q.text("%#x" % self.report_mirror_ports)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[5] = bsn_get_mirroring_reply
+
+class bsn_get_mirroring_request(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 4
+
+    def __init__(self, xid=None, report_mirror_ports=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if report_mirror_ports != None:
+            self.report_mirror_ports = report_mirror_ports
+        else:
+            self.report_mirror_ports = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!B", self.report_mirror_ports))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_get_mirroring_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 4)
+        obj.report_mirror_ports = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.report_mirror_ports != other.report_mirror_ports: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_get_mirroring_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("report_mirror_ports = ");
+                q.text("%#x" % self.report_mirror_ports)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[4] = bsn_get_mirroring_request
+
+class bsn_get_switch_pipeline_reply(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 52
+
+    def __init__(self, xid=None, pipeline=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if pipeline != None:
+            self.pipeline = pipeline
+        else:
+            self.pipeline = ""
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!256s", self.pipeline))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_get_switch_pipeline_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 52)
+        obj.pipeline = reader.read("!256s")[0].rstrip("\x00")
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.pipeline != other.pipeline: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_get_switch_pipeline_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("pipeline = ");
+                q.pp(self.pipeline)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[52] = bsn_get_switch_pipeline_reply
+
+class bsn_get_switch_pipeline_request(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 51
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_get_switch_pipeline_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 51)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_get_switch_pipeline_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[51] = bsn_get_switch_pipeline_request
+
+class bsn_image_desc_stats_reply(bsn_stats_reply):
+    version = 5
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 14
+
+    def __init__(self, xid=None, flags=None, image_checksum=None, startup_config_checksum=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if image_checksum != None:
+            self.image_checksum = image_checksum
+        else:
+            self.image_checksum = ""
+        if startup_config_checksum != None:
+            self.startup_config_checksum = startup_config_checksum
+        else:
+            self.startup_config_checksum = ""
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!256s", self.image_checksum))
+        packed.append(struct.pack("!256s", self.startup_config_checksum))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_image_desc_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 14)
+        obj.image_checksum = reader.read("!256s")[0].rstrip("\x00")
+        obj.startup_config_checksum = reader.read("!256s")[0].rstrip("\x00")
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.image_checksum != other.image_checksum: return False
+        if self.startup_config_checksum != other.startup_config_checksum: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_image_desc_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("image_checksum = ");
+                q.pp(self.image_checksum)
+                q.text(","); q.breakable()
+                q.text("startup_config_checksum = ");
+                q.pp(self.startup_config_checksum)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_reply.subtypes[14] = bsn_image_desc_stats_reply
+
+class bsn_image_desc_stats_request(bsn_stats_request):
+    version = 5
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 14
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_image_desc_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 14)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_image_desc_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_request.subtypes[14] = bsn_image_desc_stats_request
+
+class bsn_lacp_convergence_notif(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 43
+
+    def __init__(self, xid=None, convergence_status=None, port_no=None, actor_sys_priority=None, actor_sys_mac=None, actor_port_priority=None, actor_port_num=None, actor_key=None, partner_sys_priority=None, partner_sys_mac=None, partner_port_priority=None, partner_port_num=None, partner_key=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if convergence_status != None:
+            self.convergence_status = convergence_status
+        else:
+            self.convergence_status = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if actor_sys_priority != None:
+            self.actor_sys_priority = actor_sys_priority
+        else:
+            self.actor_sys_priority = 0
+        if actor_sys_mac != None:
+            self.actor_sys_mac = actor_sys_mac
+        else:
+            self.actor_sys_mac = [0,0,0,0,0,0]
+        if actor_port_priority != None:
+            self.actor_port_priority = actor_port_priority
+        else:
+            self.actor_port_priority = 0
+        if actor_port_num != None:
+            self.actor_port_num = actor_port_num
+        else:
+            self.actor_port_num = 0
+        if actor_key != None:
+            self.actor_key = actor_key
+        else:
+            self.actor_key = 0
+        if partner_sys_priority != None:
+            self.partner_sys_priority = partner_sys_priority
+        else:
+            self.partner_sys_priority = 0
+        if partner_sys_mac != None:
+            self.partner_sys_mac = partner_sys_mac
+        else:
+            self.partner_sys_mac = [0,0,0,0,0,0]
+        if partner_port_priority != None:
+            self.partner_port_priority = partner_port_priority
+        else:
+            self.partner_port_priority = 0
+        if partner_port_num != None:
+            self.partner_port_num = partner_port_num
+        else:
+            self.partner_port_num = 0
+        if partner_key != None:
+            self.partner_key = partner_key
+        else:
+            self.partner_key = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!B", self.convergence_status))
+        packed.append('\x00' * 3)
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!H", self.actor_sys_priority))
+        packed.append(struct.pack("!6B", *self.actor_sys_mac))
+        packed.append(struct.pack("!H", self.actor_port_priority))
+        packed.append(struct.pack("!H", self.actor_port_num))
+        packed.append(struct.pack("!H", self.actor_key))
+        packed.append(struct.pack("!H", self.partner_sys_priority))
+        packed.append(struct.pack("!6B", *self.partner_sys_mac))
+        packed.append(struct.pack("!H", self.partner_port_priority))
+        packed.append(struct.pack("!H", self.partner_port_num))
+        packed.append(struct.pack("!H", self.partner_key))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_lacp_convergence_notif()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 43)
+        obj.convergence_status = reader.read("!B")[0]
+        reader.skip(3)
+        obj.port_no = util.unpack_port_no(reader)
+        obj.actor_sys_priority = reader.read("!H")[0]
+        obj.actor_sys_mac = list(reader.read('!6B'))
+        obj.actor_port_priority = reader.read("!H")[0]
+        obj.actor_port_num = reader.read("!H")[0]
+        obj.actor_key = reader.read("!H")[0]
+        obj.partner_sys_priority = reader.read("!H")[0]
+        obj.partner_sys_mac = list(reader.read('!6B'))
+        obj.partner_port_priority = reader.read("!H")[0]
+        obj.partner_port_num = reader.read("!H")[0]
+        obj.partner_key = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.convergence_status != other.convergence_status: return False
+        if self.port_no != other.port_no: return False
+        if self.actor_sys_priority != other.actor_sys_priority: return False
+        if self.actor_sys_mac != other.actor_sys_mac: return False
+        if self.actor_port_priority != other.actor_port_priority: return False
+        if self.actor_port_num != other.actor_port_num: return False
+        if self.actor_key != other.actor_key: return False
+        if self.partner_sys_priority != other.partner_sys_priority: return False
+        if self.partner_sys_mac != other.partner_sys_mac: return False
+        if self.partner_port_priority != other.partner_port_priority: return False
+        if self.partner_port_num != other.partner_port_num: return False
+        if self.partner_key != other.partner_key: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_lacp_convergence_notif {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("convergence_status = ");
+                q.text("%#x" % self.convergence_status)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("actor_sys_priority = ");
+                q.text("%#x" % self.actor_sys_priority)
+                q.text(","); q.breakable()
+                q.text("actor_sys_mac = ");
+                q.text(util.pretty_mac(self.actor_sys_mac))
+                q.text(","); q.breakable()
+                q.text("actor_port_priority = ");
+                q.text("%#x" % self.actor_port_priority)
+                q.text(","); q.breakable()
+                q.text("actor_port_num = ");
+                q.text("%#x" % self.actor_port_num)
+                q.text(","); q.breakable()
+                q.text("actor_key = ");
+                q.text("%#x" % self.actor_key)
+                q.text(","); q.breakable()
+                q.text("partner_sys_priority = ");
+                q.text("%#x" % self.partner_sys_priority)
+                q.text(","); q.breakable()
+                q.text("partner_sys_mac = ");
+                q.text(util.pretty_mac(self.partner_sys_mac))
+                q.text(","); q.breakable()
+                q.text("partner_port_priority = ");
+                q.text("%#x" % self.partner_port_priority)
+                q.text(","); q.breakable()
+                q.text("partner_port_num = ");
+                q.text("%#x" % self.partner_port_num)
+                q.text(","); q.breakable()
+                q.text("partner_key = ");
+                q.text("%#x" % self.partner_key)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[43] = bsn_lacp_convergence_notif
+
+class bsn_lacp_stats_reply(bsn_stats_reply):
+    version = 5
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 1
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_lacp_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 1)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.bsn_lacp_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_lacp_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_reply.subtypes[1] = bsn_lacp_stats_reply
+
+class bsn_lacp_stats_request(bsn_stats_request):
+    version = 5
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 1
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_lacp_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 1)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_lacp_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_request.subtypes[1] = bsn_lacp_stats_request
+
+class bsn_log(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 63
+
+    def __init__(self, xid=None, loglevel=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if loglevel != None:
+            self.loglevel = loglevel
+        else:
+            self.loglevel = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!B", self.loglevel))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_log()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 63)
+        obj.loglevel = reader.read("!B")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.loglevel != other.loglevel: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_log {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("loglevel = ");
+                q.text("%#x" % self.loglevel)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[63] = bsn_log
+
+class bsn_lua_command_reply(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 66
+
+    def __init__(self, xid=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_lua_command_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 66)
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_lua_command_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[66] = bsn_lua_command_reply
+
+class bsn_lua_command_request(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 65
+
+    def __init__(self, xid=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_lua_command_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 65)
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_lua_command_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[65] = bsn_lua_command_request
+
+class bsn_lua_notification(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 67
+
+    def __init__(self, xid=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_lua_notification()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 67)
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_lua_notification {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[67] = bsn_lua_notification
+
+class bsn_lua_upload(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 64
+
+    def __init__(self, xid=None, flags=None, filename=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if filename != None:
+            self.filename = filename
+        else:
+            self.filename = ""
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(struct.pack("!64s", self.filename))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_lua_upload()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 64)
+        obj.flags = reader.read("!H")[0]
+        obj.filename = reader.read("!64s")[0].rstrip("\x00")
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.filename != other.filename: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_lua_upload {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("filename = ");
+                q.pp(self.filename)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[64] = bsn_lua_upload
+
+class bsn_pdu_rx_reply(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 34
+
+    def __init__(self, xid=None, status=None, port_no=None, slot_num=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if slot_num != None:
+            self.slot_num = slot_num
+        else:
+            self.slot_num = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.status))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!B", self.slot_num))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_pdu_rx_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 34)
+        obj.status = reader.read("!L")[0]
+        obj.port_no = util.unpack_port_no(reader)
+        obj.slot_num = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.status != other.status: return False
+        if self.port_no != other.port_no: return False
+        if self.slot_num != other.slot_num: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_pdu_rx_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("slot_num = ");
+                q.text("%#x" % self.slot_num)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[34] = bsn_pdu_rx_reply
+
+class bsn_pdu_rx_request(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 33
+
+    def __init__(self, xid=None, timeout_ms=None, port_no=None, slot_num=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if timeout_ms != None:
+            self.timeout_ms = timeout_ms
+        else:
+            self.timeout_ms = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if slot_num != None:
+            self.slot_num = slot_num
+        else:
+            self.slot_num = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.timeout_ms))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!B", self.slot_num))
+        packed.append('\x00' * 3)
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_pdu_rx_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 33)
+        obj.timeout_ms = reader.read("!L")[0]
+        obj.port_no = util.unpack_port_no(reader)
+        obj.slot_num = reader.read("!B")[0]
+        reader.skip(3)
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.timeout_ms != other.timeout_ms: return False
+        if self.port_no != other.port_no: return False
+        if self.slot_num != other.slot_num: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_pdu_rx_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("timeout_ms = ");
+                q.text("%#x" % self.timeout_ms)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("slot_num = ");
+                q.text("%#x" % self.slot_num)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[33] = bsn_pdu_rx_request
+
+class bsn_pdu_rx_timeout(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 35
+
+    def __init__(self, xid=None, port_no=None, slot_num=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if slot_num != None:
+            self.slot_num = slot_num
+        else:
+            self.slot_num = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!B", self.slot_num))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_pdu_rx_timeout()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 35)
+        obj.port_no = util.unpack_port_no(reader)
+        obj.slot_num = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.port_no != other.port_no: return False
+        if self.slot_num != other.slot_num: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_pdu_rx_timeout {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("slot_num = ");
+                q.text("%#x" % self.slot_num)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[35] = bsn_pdu_rx_timeout
+
+class bsn_pdu_tx_reply(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 32
+
+    def __init__(self, xid=None, status=None, port_no=None, slot_num=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if slot_num != None:
+            self.slot_num = slot_num
+        else:
+            self.slot_num = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.status))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!B", self.slot_num))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_pdu_tx_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 32)
+        obj.status = reader.read("!L")[0]
+        obj.port_no = util.unpack_port_no(reader)
+        obj.slot_num = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.status != other.status: return False
+        if self.port_no != other.port_no: return False
+        if self.slot_num != other.slot_num: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_pdu_tx_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("slot_num = ");
+                q.text("%#x" % self.slot_num)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[32] = bsn_pdu_tx_reply
+
+class bsn_pdu_tx_request(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 31
+
+    def __init__(self, xid=None, tx_interval_ms=None, port_no=None, slot_num=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if tx_interval_ms != None:
+            self.tx_interval_ms = tx_interval_ms
+        else:
+            self.tx_interval_ms = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if slot_num != None:
+            self.slot_num = slot_num
+        else:
+            self.slot_num = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.tx_interval_ms))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!B", self.slot_num))
+        packed.append('\x00' * 3)
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_pdu_tx_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 31)
+        obj.tx_interval_ms = reader.read("!L")[0]
+        obj.port_no = util.unpack_port_no(reader)
+        obj.slot_num = reader.read("!B")[0]
+        reader.skip(3)
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.tx_interval_ms != other.tx_interval_ms: return False
+        if self.port_no != other.port_no: return False
+        if self.slot_num != other.slot_num: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_pdu_tx_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("tx_interval_ms = ");
+                q.text("%#x" % self.tx_interval_ms)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("slot_num = ");
+                q.text("%#x" % self.slot_num)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[31] = bsn_pdu_tx_request
+
+class bsn_port_counter_stats_reply(bsn_stats_reply):
+    version = 5
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 8
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_port_counter_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 8)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.bsn_port_counter_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_port_counter_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_reply.subtypes[8] = bsn_port_counter_stats_reply
+
+class bsn_port_counter_stats_request(bsn_stats_request):
+    version = 5
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 8
+
+    def __init__(self, xid=None, flags=None, port_no=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(util.pack_port_no(self.port_no))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_port_counter_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 8)
+        obj.port_no = util.unpack_port_no(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.port_no != other.port_no: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_port_counter_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+            q.breakable()
+        q.text('}')
+
+bsn_stats_request.subtypes[8] = bsn_port_counter_stats_request
+
+class bsn_set_aux_cxns_reply(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 59
+
+    def __init__(self, xid=None, num_aux=None, status=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if num_aux != None:
+            self.num_aux = num_aux
+        else:
+            self.num_aux = 0
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.num_aux))
+        packed.append(struct.pack("!L", self.status))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_aux_cxns_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 59)
+        obj.num_aux = reader.read("!L")[0]
+        obj.status = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.num_aux != other.num_aux: return False
+        if self.status != other.status: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_aux_cxns_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("num_aux = ");
+                q.text("%#x" % self.num_aux)
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[59] = bsn_set_aux_cxns_reply
+
+class bsn_set_aux_cxns_request(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 58
+
+    def __init__(self, xid=None, num_aux=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if num_aux != None:
+            self.num_aux = num_aux
+        else:
+            self.num_aux = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.num_aux))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_aux_cxns_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 58)
+        obj.num_aux = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.num_aux != other.num_aux: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_aux_cxns_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("num_aux = ");
+                q.text("%#x" % self.num_aux)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[58] = bsn_set_aux_cxns_request
+
+class bsn_set_lacp_reply(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 42
+
+    def __init__(self, xid=None, status=None, port_no=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.status))
+        packed.append(util.pack_port_no(self.port_no))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_lacp_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 42)
+        obj.status = reader.read("!L")[0]
+        obj.port_no = util.unpack_port_no(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.status != other.status: return False
+        if self.port_no != other.port_no: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_lacp_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[42] = bsn_set_lacp_reply
+
+class bsn_set_lacp_request(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 41
+
+    def __init__(self, xid=None, enabled=None, port_no=None, actor_sys_priority=None, actor_sys_mac=None, actor_port_priority=None, actor_port_num=None, actor_key=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if enabled != None:
+            self.enabled = enabled
+        else:
+            self.enabled = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if actor_sys_priority != None:
+            self.actor_sys_priority = actor_sys_priority
+        else:
+            self.actor_sys_priority = 0
+        if actor_sys_mac != None:
+            self.actor_sys_mac = actor_sys_mac
+        else:
+            self.actor_sys_mac = [0,0,0,0,0,0]
+        if actor_port_priority != None:
+            self.actor_port_priority = actor_port_priority
+        else:
+            self.actor_port_priority = 0
+        if actor_port_num != None:
+            self.actor_port_num = actor_port_num
+        else:
+            self.actor_port_num = 0
+        if actor_key != None:
+            self.actor_key = actor_key
+        else:
+            self.actor_key = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!B", self.enabled))
+        packed.append('\x00' * 3)
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!H", self.actor_sys_priority))
+        packed.append(struct.pack("!6B", *self.actor_sys_mac))
+        packed.append(struct.pack("!H", self.actor_port_priority))
+        packed.append(struct.pack("!H", self.actor_port_num))
+        packed.append(struct.pack("!H", self.actor_key))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_lacp_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 41)
+        obj.enabled = reader.read("!B")[0]
+        reader.skip(3)
+        obj.port_no = util.unpack_port_no(reader)
+        obj.actor_sys_priority = reader.read("!H")[0]
+        obj.actor_sys_mac = list(reader.read('!6B'))
+        obj.actor_port_priority = reader.read("!H")[0]
+        obj.actor_port_num = reader.read("!H")[0]
+        obj.actor_key = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.enabled != other.enabled: return False
+        if self.port_no != other.port_no: return False
+        if self.actor_sys_priority != other.actor_sys_priority: return False
+        if self.actor_sys_mac != other.actor_sys_mac: return False
+        if self.actor_port_priority != other.actor_port_priority: return False
+        if self.actor_port_num != other.actor_port_num: return False
+        if self.actor_key != other.actor_key: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_lacp_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("enabled = ");
+                q.text("%#x" % self.enabled)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("actor_sys_priority = ");
+                q.text("%#x" % self.actor_sys_priority)
+                q.text(","); q.breakable()
+                q.text("actor_sys_mac = ");
+                q.text(util.pretty_mac(self.actor_sys_mac))
+                q.text(","); q.breakable()
+                q.text("actor_port_priority = ");
+                q.text("%#x" % self.actor_port_priority)
+                q.text(","); q.breakable()
+                q.text("actor_port_num = ");
+                q.text("%#x" % self.actor_port_num)
+                q.text(","); q.breakable()
+                q.text("actor_key = ");
+                q.text("%#x" % self.actor_key)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[41] = bsn_set_lacp_request
+
+class bsn_set_mirroring(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 3
+
+    def __init__(self, xid=None, report_mirror_ports=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if report_mirror_ports != None:
+            self.report_mirror_ports = report_mirror_ports
+        else:
+            self.report_mirror_ports = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!B", self.report_mirror_ports))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_mirroring()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 3)
+        obj.report_mirror_ports = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.report_mirror_ports != other.report_mirror_ports: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_mirroring {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("report_mirror_ports = ");
+                q.text("%#x" % self.report_mirror_ports)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[3] = bsn_set_mirroring
+
+class bsn_set_pktin_suppression_reply(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 25
+
+    def __init__(self, xid=None, status=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.status))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_pktin_suppression_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 25)
+        obj.status = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.status != other.status: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_pktin_suppression_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[25] = bsn_set_pktin_suppression_reply
+
+class bsn_set_pktin_suppression_request(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 11
+
+    def __init__(self, xid=None, enabled=None, idle_timeout=None, hard_timeout=None, priority=None, cookie=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if enabled != None:
+            self.enabled = enabled
+        else:
+            self.enabled = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!B", self.enabled))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!Q", self.cookie))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_pktin_suppression_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 11)
+        obj.enabled = reader.read("!B")[0]
+        reader.skip(1)
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.cookie = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.enabled != other.enabled: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.priority != other.priority: return False
+        if self.cookie != other.cookie: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_pktin_suppression_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("enabled = ");
+                q.text("%#x" % self.enabled)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[11] = bsn_set_pktin_suppression_request
+
+class bsn_set_switch_pipeline_reply(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 54
+
+    def __init__(self, xid=None, status=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.status))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_switch_pipeline_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 54)
+        obj.status = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.status != other.status: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_switch_pipeline_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[54] = bsn_set_switch_pipeline_reply
+
+class bsn_set_switch_pipeline_request(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 53
+
+    def __init__(self, xid=None, pipeline=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if pipeline != None:
+            self.pipeline = pipeline
+        else:
+            self.pipeline = ""
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!256s", self.pipeline))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_set_switch_pipeline_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 53)
+        obj.pipeline = reader.read("!256s")[0].rstrip("\x00")
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.pipeline != other.pipeline: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_set_switch_pipeline_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("pipeline = ");
+                q.pp(self.pipeline)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[53] = bsn_set_switch_pipeline_request
+
+class bsn_switch_pipeline_stats_reply(bsn_stats_reply):
+    version = 5
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 6
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_switch_pipeline_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 6)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.bsn_switch_pipeline_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_switch_pipeline_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_reply.subtypes[6] = bsn_switch_pipeline_stats_reply
+
+class bsn_switch_pipeline_stats_request(bsn_stats_request):
+    version = 5
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 6
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_switch_pipeline_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 6)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_switch_pipeline_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_request.subtypes[6] = bsn_switch_pipeline_stats_request
+
+class bsn_table_checksum_stats_reply(bsn_stats_reply):
+    version = 5
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 11
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_table_checksum_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 11)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.bsn_table_checksum_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_table_checksum_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_reply.subtypes[11] = bsn_table_checksum_stats_reply
+
+class bsn_table_checksum_stats_request(bsn_stats_request):
+    version = 5
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 11
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_table_checksum_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 11)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_table_checksum_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_request.subtypes[11] = bsn_table_checksum_stats_request
+
+class bsn_table_set_buckets_size(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 61
+
+    def __init__(self, xid=None, table_id=None, buckets_size=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if buckets_size != None:
+            self.buckets_size = buckets_size
+        else:
+            self.buckets_size = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!L", self.buckets_size))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_table_set_buckets_size()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 61)
+        reader.skip(1)
+        obj.table_id = reader.read("!B")[0]
+        reader.skip(2)
+        obj.buckets_size = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.table_id != other.table_id: return False
+        if self.buckets_size != other.buckets_size: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_table_set_buckets_size {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("buckets_size = ");
+                q.text("%#x" % self.buckets_size)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[61] = bsn_table_set_buckets_size
+
+class bsn_takeover(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 69
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_takeover()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 69)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_takeover {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[69] = bsn_takeover
+
+class bsn_time_reply(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 45
+
+    def __init__(self, xid=None, time_ms=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if time_ms != None:
+            self.time_ms = time_ms
+        else:
+            self.time_ms = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!Q", self.time_ms))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_time_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 45)
+        obj.time_ms = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.time_ms != other.time_ms: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_time_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("time_ms = ");
+                q.text("%#x" % self.time_ms)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[45] = bsn_time_reply
+
+class bsn_time_request(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 44
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_time_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 44)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_time_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[44] = bsn_time_request
+
+class bsn_virtual_port_create_reply(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 16
+
+    def __init__(self, xid=None, status=None, vport_no=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        if vport_no != None:
+            self.vport_no = vport_no
+        else:
+            self.vport_no = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.status))
+        packed.append(struct.pack("!L", self.vport_no))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_virtual_port_create_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 16)
+        obj.status = reader.read("!L")[0]
+        obj.vport_no = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.status != other.status: return False
+        if self.vport_no != other.vport_no: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_virtual_port_create_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+                q.text(","); q.breakable()
+                q.text("vport_no = ");
+                q.text("%#x" % self.vport_no)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[16] = bsn_virtual_port_create_reply
+
+class bsn_virtual_port_create_request(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 15
+
+    def __init__(self, xid=None, vport=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if vport != None:
+            self.vport = vport
+        else:
+            self.vport = ofp.bsn_vport()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(self.vport.pack())
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_virtual_port_create_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 15)
+        obj.vport = ofp.bsn_vport.unpack(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.vport != other.vport: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_virtual_port_create_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("vport = ");
+                q.pp(self.vport)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[15] = bsn_virtual_port_create_request
+
+class bsn_virtual_port_remove_reply(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 26
+
+    def __init__(self, xid=None, status=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if status != None:
+            self.status = status
+        else:
+            self.status = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.status))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_virtual_port_remove_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 26)
+        obj.status = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.status != other.status: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_virtual_port_remove_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("status = ");
+                q.text("%#x" % self.status)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[26] = bsn_virtual_port_remove_reply
+
+class bsn_virtual_port_remove_request(bsn_header):
+    version = 5
+    type = 4
+    experimenter = 6035143
+    subtype = 17
+
+    def __init__(self, xid=None, vport_no=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if vport_no != None:
+            self.vport_no = vport_no
+        else:
+            self.vport_no = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.vport_no))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_virtual_port_remove_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 17)
+        obj.vport_no = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.vport_no != other.vport_no: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_virtual_port_remove_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("vport_no = ");
+                q.text("%#x" % self.vport_no)
+            q.breakable()
+        q.text('}')
+
+bsn_header.subtypes[17] = bsn_virtual_port_remove_request
+
+class bsn_vlan_counter_stats_reply(bsn_stats_reply):
+    version = 5
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 9
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vlan_counter_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 9)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.bsn_vlan_counter_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vlan_counter_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_reply.subtypes[9] = bsn_vlan_counter_stats_reply
+
+class bsn_vlan_counter_stats_request(bsn_stats_request):
+    version = 5
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 9
+
+    def __init__(self, xid=None, flags=None, vlan_vid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if vlan_vid != None:
+            self.vlan_vid = vlan_vid
+        else:
+            self.vlan_vid = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!H", self.vlan_vid))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vlan_counter_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 9)
+        obj.vlan_vid = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.vlan_vid != other.vlan_vid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vlan_counter_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("vlan_vid = ");
+                q.text("%#x" % self.vlan_vid)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_request.subtypes[9] = bsn_vlan_counter_stats_request
+
+class bsn_vrf_counter_stats_reply(bsn_stats_reply):
+    version = 5
+    type = 19
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 15
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vrf_counter_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 15)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.bsn_vrf_counter_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vrf_counter_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_reply.subtypes[15] = bsn_vrf_counter_stats_reply
+
+class bsn_vrf_counter_stats_request(bsn_stats_request):
+    version = 5
+    type = 18
+    stats_type = 65535
+    experimenter = 6035143
+    subtype = 15
+
+    def __init__(self, xid=None, flags=None, vrf=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if vrf != None:
+            self.vrf = vrf
+        else:
+            self.vrf = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        packed.append(struct.pack("!L", self.vrf))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vrf_counter_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 65535)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _subtype = reader.read("!L")[0]
+        assert(_subtype == 15)
+        obj.vrf = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.vrf != other.vrf: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vrf_counter_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("vrf = ");
+                q.text("%#x" % self.vrf)
+            q.breakable()
+        q.text('}')
+
+bsn_stats_request.subtypes[15] = bsn_vrf_counter_stats_request
+
+class bundle_add_msg(message):
+    version = 5
+    type = 34
+
+    def __init__(self, xid=None, bundle_id=None, flags=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if bundle_id != None:
+            self.bundle_id = bundle_id
+        else:
+            self.bundle_id = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.bundle_id))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bundle_add_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 34)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.bundle_id = reader.read("!L")[0]
+        reader.skip(2)
+        obj.flags = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.bundle_id != other.bundle_id: return False
+        if self.flags != other.flags: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bundle_add_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("bundle_id = ");
+                q.text("%#x" % self.bundle_id)
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[34] = bundle_add_msg
+
+class bundle_ctrl_msg(message):
+    version = 5
+    type = 33
+
+    def __init__(self, xid=None, bundle_id=None, bundle_ctrl_type=None, flags=None, properties=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if bundle_id != None:
+            self.bundle_id = bundle_id
+        else:
+            self.bundle_id = 0
+        if bundle_ctrl_type != None:
+            self.bundle_ctrl_type = bundle_ctrl_type
+        else:
+            self.bundle_ctrl_type = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if properties != None:
+            self.properties = properties
+        else:
+            self.properties = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.bundle_id))
+        packed.append(struct.pack("!H", self.bundle_ctrl_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(loxi.generic_util.pack_list(self.properties))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bundle_ctrl_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 33)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.bundle_id = reader.read("!L")[0]
+        obj.bundle_ctrl_type = reader.read("!H")[0]
+        obj.flags = reader.read("!H")[0]
+        obj.properties = loxi.generic_util.unpack_list(reader, ofp.bundle_prop.bundle_prop.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.bundle_id != other.bundle_id: return False
+        if self.bundle_ctrl_type != other.bundle_ctrl_type: return False
+        if self.flags != other.flags: return False
+        if self.properties != other.properties: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bundle_ctrl_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("bundle_id = ");
+                q.text("%#x" % self.bundle_id)
+                q.text(","); q.breakable()
+                q.text("bundle_ctrl_type = ");
+                q.text("%#x" % self.bundle_ctrl_type)
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("properties = ");
+                q.pp(self.properties)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[33] = bundle_ctrl_msg
+
+class bundle_failed_error_msg(error_msg):
+    version = 5
+    type = 1
+    err_type = 17
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bundle_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 17)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bundle_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[17] = bundle_failed_error_msg
+
+class desc_stats_reply(stats_reply):
+    version = 5
+    type = 19
+    stats_type = 0
+
+    def __init__(self, xid=None, flags=None, mfr_desc=None, hw_desc=None, sw_desc=None, serial_num=None, dp_desc=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if mfr_desc != None:
+            self.mfr_desc = mfr_desc
+        else:
+            self.mfr_desc = ""
+        if hw_desc != None:
+            self.hw_desc = hw_desc
+        else:
+            self.hw_desc = ""
+        if sw_desc != None:
+            self.sw_desc = sw_desc
+        else:
+            self.sw_desc = ""
+        if serial_num != None:
+            self.serial_num = serial_num
+        else:
+            self.serial_num = ""
+        if dp_desc != None:
+            self.dp_desc = dp_desc
+        else:
+            self.dp_desc = ""
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!256s", self.mfr_desc))
+        packed.append(struct.pack("!256s", self.hw_desc))
+        packed.append(struct.pack("!256s", self.sw_desc))
+        packed.append(struct.pack("!32s", self.serial_num))
+        packed.append(struct.pack("!256s", self.dp_desc))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = desc_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 0)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.mfr_desc = reader.read("!256s")[0].rstrip("\x00")
+        obj.hw_desc = reader.read("!256s")[0].rstrip("\x00")
+        obj.sw_desc = reader.read("!256s")[0].rstrip("\x00")
+        obj.serial_num = reader.read("!32s")[0].rstrip("\x00")
+        obj.dp_desc = reader.read("!256s")[0].rstrip("\x00")
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.mfr_desc != other.mfr_desc: return False
+        if self.hw_desc != other.hw_desc: return False
+        if self.sw_desc != other.sw_desc: return False
+        if self.serial_num != other.serial_num: return False
+        if self.dp_desc != other.dp_desc: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("desc_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("mfr_desc = ");
+                q.pp(self.mfr_desc)
+                q.text(","); q.breakable()
+                q.text("hw_desc = ");
+                q.pp(self.hw_desc)
+                q.text(","); q.breakable()
+                q.text("sw_desc = ");
+                q.pp(self.sw_desc)
+                q.text(","); q.breakable()
+                q.text("serial_num = ");
+                q.pp(self.serial_num)
+                q.text(","); q.breakable()
+                q.text("dp_desc = ");
+                q.pp(self.dp_desc)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[0] = desc_stats_reply
+
+class desc_stats_request(stats_request):
+    version = 5
+    type = 18
+    stats_type = 0
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = desc_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 0)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("desc_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[0] = desc_stats_request
+
+class echo_reply(message):
+    version = 5
+    type = 3
+
+    def __init__(self, xid=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = echo_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 3)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("echo_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[3] = echo_reply
+
+class echo_request(message):
+    version = 5
+    type = 2
+
+    def __init__(self, xid=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = echo_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 2)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("echo_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[2] = echo_request
+
+class experimenter_error_msg(error_msg):
+    version = 5
+    type = 1
+    err_type = 65535
+
+    def __init__(self, xid=None, subtype=None, experimenter=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.subtype))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = experimenter_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 65535)
+        obj.subtype = reader.read("!H")[0]
+        obj.experimenter = reader.read("!L")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.subtype != other.subtype: return False
+        if self.experimenter != other.experimenter: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("subtype = ");
+                q.text("%#x" % self.subtype)
+                q.text(","); q.breakable()
+                q.text("experimenter = ");
+                q.text("%#x" % self.experimenter)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[65535] = experimenter_error_msg
+
+class features_reply(message):
+    version = 5
+    type = 6
+
+    def __init__(self, xid=None, datapath_id=None, n_buffers=None, n_tables=None, auxiliary_id=None, capabilities=None, reserved=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if datapath_id != None:
+            self.datapath_id = datapath_id
+        else:
+            self.datapath_id = 0
+        if n_buffers != None:
+            self.n_buffers = n_buffers
+        else:
+            self.n_buffers = 0
+        if n_tables != None:
+            self.n_tables = n_tables
+        else:
+            self.n_tables = 0
+        if auxiliary_id != None:
+            self.auxiliary_id = auxiliary_id
+        else:
+            self.auxiliary_id = 0
+        if capabilities != None:
+            self.capabilities = capabilities
+        else:
+            self.capabilities = 0
+        if reserved != None:
+            self.reserved = reserved
+        else:
+            self.reserved = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!Q", self.datapath_id))
+        packed.append(struct.pack("!L", self.n_buffers))
+        packed.append(struct.pack("!B", self.n_tables))
+        packed.append(struct.pack("!B", self.auxiliary_id))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!L", self.capabilities))
+        packed.append(struct.pack("!L", self.reserved))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = features_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 6)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.datapath_id = reader.read("!Q")[0]
+        obj.n_buffers = reader.read("!L")[0]
+        obj.n_tables = reader.read("!B")[0]
+        obj.auxiliary_id = reader.read("!B")[0]
+        reader.skip(2)
+        obj.capabilities = reader.read("!L")[0]
+        obj.reserved = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.datapath_id != other.datapath_id: return False
+        if self.n_buffers != other.n_buffers: return False
+        if self.n_tables != other.n_tables: return False
+        if self.auxiliary_id != other.auxiliary_id: return False
+        if self.capabilities != other.capabilities: return False
+        if self.reserved != other.reserved: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("features_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("datapath_id = ");
+                q.text("%#x" % self.datapath_id)
+                q.text(","); q.breakable()
+                q.text("n_buffers = ");
+                q.text("%#x" % self.n_buffers)
+                q.text(","); q.breakable()
+                q.text("n_tables = ");
+                q.text("%#x" % self.n_tables)
+                q.text(","); q.breakable()
+                q.text("auxiliary_id = ");
+                q.text("%#x" % self.auxiliary_id)
+                q.text(","); q.breakable()
+                q.text("capabilities = ");
+                q.text("%#x" % self.capabilities)
+                q.text(","); q.breakable()
+                q.text("reserved = ");
+                q.text("%#x" % self.reserved)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[6] = features_reply
+
+class features_request(message):
+    version = 5
+    type = 5
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = features_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 5)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("features_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+message.subtypes[5] = features_request
+
+class flow_mod(message):
+    subtypes = {}
+
+    version = 5
+    type = 14
+
+    def __init__(self, xid=None, cookie=None, cookie_mask=None, table_id=None, _command=None, idle_timeout=None, hard_timeout=None, priority=None, buffer_id=None, out_port=None, out_group=None, flags=None, match=None, instructions=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if cookie_mask != None:
+            self.cookie_mask = cookie_mask
+        else:
+            self.cookie_mask = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if _command != None:
+            self._command = _command
+        else:
+            self._command = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if out_group != None:
+            self.out_group = out_group
+        else:
+            self.out_group = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if instructions != None:
+            self.instructions = instructions
+        else:
+            self.instructions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.cookie_mask))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append(util.pack_fm_cmd(self._command))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!L", self.out_group))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 2)
+        packed.append(self.match.pack())
+        packed.append(loxi.generic_util.pack_list(self.instructions))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('B', 25)
+        subclass = flow_mod.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = flow_mod()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 14)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.cookie = reader.read("!Q")[0]
+        obj.cookie_mask = reader.read("!Q")[0]
+        obj.table_id = reader.read("!B")[0]
+        obj._command = util.unpack_fm_cmd(reader)
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.out_port = util.unpack_port_no(reader)
+        obj.out_group = reader.read("!L")[0]
+        obj.flags = reader.read("!H")[0]
+        reader.skip(2)
+        obj.match = ofp.match.unpack(reader)
+        obj.instructions = loxi.generic_util.unpack_list(reader, ofp.instruction.instruction.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.cookie != other.cookie: return False
+        if self.cookie_mask != other.cookie_mask: return False
+        if self.table_id != other.table_id: return False
+        if self._command != other._command: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.priority != other.priority: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.out_port != other.out_port: return False
+        if self.out_group != other.out_group: return False
+        if self.flags != other.flags: return False
+        if self.match != other.match: return False
+        if self.instructions != other.instructions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_mod {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("cookie_mask = ");
+                q.text("%#x" % self.cookie_mask)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("out_group = ");
+                q.text("%#x" % self.out_group)
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("instructions = ");
+                q.pp(self.instructions)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[14] = flow_mod
+
+class flow_add(flow_mod):
+    version = 5
+    type = 14
+    _command = 0
+
+    def __init__(self, xid=None, cookie=None, cookie_mask=None, table_id=None, idle_timeout=None, hard_timeout=None, priority=None, buffer_id=None, out_port=None, out_group=None, flags=None, importance=None, match=None, instructions=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if cookie_mask != None:
+            self.cookie_mask = cookie_mask
+        else:
+            self.cookie_mask = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if out_group != None:
+            self.out_group = out_group
+        else:
+            self.out_group = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if importance != None:
+            self.importance = importance
+        else:
+            self.importance = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if instructions != None:
+            self.instructions = instructions
+        else:
+            self.instructions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.cookie_mask))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append(util.pack_fm_cmd(self._command))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!L", self.out_group))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(struct.pack("!H", self.importance))
+        packed.append(self.match.pack())
+        packed.append(loxi.generic_util.pack_list(self.instructions))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_add()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 14)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.cookie = reader.read("!Q")[0]
+        obj.cookie_mask = reader.read("!Q")[0]
+        obj.table_id = reader.read("!B")[0]
+        __command = util.unpack_fm_cmd(reader)
+        assert(__command == 0)
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.out_port = util.unpack_port_no(reader)
+        obj.out_group = reader.read("!L")[0]
+        obj.flags = reader.read("!H")[0]
+        obj.importance = reader.read("!H")[0]
+        obj.match = ofp.match.unpack(reader)
+        obj.instructions = loxi.generic_util.unpack_list(reader, ofp.instruction.instruction.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.cookie != other.cookie: return False
+        if self.cookie_mask != other.cookie_mask: return False
+        if self.table_id != other.table_id: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.priority != other.priority: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.out_port != other.out_port: return False
+        if self.out_group != other.out_group: return False
+        if self.flags != other.flags: return False
+        if self.importance != other.importance: return False
+        if self.match != other.match: return False
+        if self.instructions != other.instructions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_add {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("cookie_mask = ");
+                q.text("%#x" % self.cookie_mask)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("out_group = ");
+                q.text("%#x" % self.out_group)
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("importance = ");
+                q.text("%#x" % self.importance)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("instructions = ");
+                q.pp(self.instructions)
+            q.breakable()
+        q.text('}')
+
+flow_mod.subtypes[0] = flow_add
+
+class flow_delete(flow_mod):
+    version = 5
+    type = 14
+    _command = 3
+
+    def __init__(self, xid=None, cookie=None, cookie_mask=None, table_id=None, idle_timeout=None, hard_timeout=None, priority=None, buffer_id=None, out_port=None, out_group=None, flags=None, importance=None, match=None, instructions=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if cookie_mask != None:
+            self.cookie_mask = cookie_mask
+        else:
+            self.cookie_mask = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if out_group != None:
+            self.out_group = out_group
+        else:
+            self.out_group = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if importance != None:
+            self.importance = importance
+        else:
+            self.importance = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if instructions != None:
+            self.instructions = instructions
+        else:
+            self.instructions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.cookie_mask))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append(util.pack_fm_cmd(self._command))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!L", self.out_group))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(struct.pack("!H", self.importance))
+        packed.append(self.match.pack())
+        packed.append(loxi.generic_util.pack_list(self.instructions))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_delete()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 14)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.cookie = reader.read("!Q")[0]
+        obj.cookie_mask = reader.read("!Q")[0]
+        obj.table_id = reader.read("!B")[0]
+        __command = util.unpack_fm_cmd(reader)
+        assert(__command == 3)
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.out_port = util.unpack_port_no(reader)
+        obj.out_group = reader.read("!L")[0]
+        obj.flags = reader.read("!H")[0]
+        obj.importance = reader.read("!H")[0]
+        obj.match = ofp.match.unpack(reader)
+        obj.instructions = loxi.generic_util.unpack_list(reader, ofp.instruction.instruction.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.cookie != other.cookie: return False
+        if self.cookie_mask != other.cookie_mask: return False
+        if self.table_id != other.table_id: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.priority != other.priority: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.out_port != other.out_port: return False
+        if self.out_group != other.out_group: return False
+        if self.flags != other.flags: return False
+        if self.importance != other.importance: return False
+        if self.match != other.match: return False
+        if self.instructions != other.instructions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_delete {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("cookie_mask = ");
+                q.text("%#x" % self.cookie_mask)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("out_group = ");
+                q.text("%#x" % self.out_group)
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("importance = ");
+                q.text("%#x" % self.importance)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("instructions = ");
+                q.pp(self.instructions)
+            q.breakable()
+        q.text('}')
+
+flow_mod.subtypes[3] = flow_delete
+
+class flow_delete_strict(flow_mod):
+    version = 5
+    type = 14
+    _command = 4
+
+    def __init__(self, xid=None, cookie=None, cookie_mask=None, table_id=None, idle_timeout=None, hard_timeout=None, priority=None, buffer_id=None, out_port=None, out_group=None, flags=None, importance=None, match=None, instructions=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if cookie_mask != None:
+            self.cookie_mask = cookie_mask
+        else:
+            self.cookie_mask = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if out_group != None:
+            self.out_group = out_group
+        else:
+            self.out_group = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if importance != None:
+            self.importance = importance
+        else:
+            self.importance = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if instructions != None:
+            self.instructions = instructions
+        else:
+            self.instructions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.cookie_mask))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append(util.pack_fm_cmd(self._command))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!L", self.out_group))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(struct.pack("!H", self.importance))
+        packed.append(self.match.pack())
+        packed.append(loxi.generic_util.pack_list(self.instructions))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_delete_strict()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 14)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.cookie = reader.read("!Q")[0]
+        obj.cookie_mask = reader.read("!Q")[0]
+        obj.table_id = reader.read("!B")[0]
+        __command = util.unpack_fm_cmd(reader)
+        assert(__command == 4)
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.out_port = util.unpack_port_no(reader)
+        obj.out_group = reader.read("!L")[0]
+        obj.flags = reader.read("!H")[0]
+        obj.importance = reader.read("!H")[0]
+        obj.match = ofp.match.unpack(reader)
+        obj.instructions = loxi.generic_util.unpack_list(reader, ofp.instruction.instruction.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.cookie != other.cookie: return False
+        if self.cookie_mask != other.cookie_mask: return False
+        if self.table_id != other.table_id: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.priority != other.priority: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.out_port != other.out_port: return False
+        if self.out_group != other.out_group: return False
+        if self.flags != other.flags: return False
+        if self.importance != other.importance: return False
+        if self.match != other.match: return False
+        if self.instructions != other.instructions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_delete_strict {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("cookie_mask = ");
+                q.text("%#x" % self.cookie_mask)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("out_group = ");
+                q.text("%#x" % self.out_group)
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("importance = ");
+                q.text("%#x" % self.importance)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("instructions = ");
+                q.pp(self.instructions)
+            q.breakable()
+        q.text('}')
+
+flow_mod.subtypes[4] = flow_delete_strict
+
+class flow_mod_failed_error_msg(error_msg):
+    version = 5
+    type = 1
+    err_type = 5
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_mod_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 5)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_mod_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[5] = flow_mod_failed_error_msg
+
+class flow_modify(flow_mod):
+    version = 5
+    type = 14
+    _command = 1
+
+    def __init__(self, xid=None, cookie=None, cookie_mask=None, table_id=None, idle_timeout=None, hard_timeout=None, priority=None, buffer_id=None, out_port=None, out_group=None, flags=None, importance=None, match=None, instructions=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if cookie_mask != None:
+            self.cookie_mask = cookie_mask
+        else:
+            self.cookie_mask = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if out_group != None:
+            self.out_group = out_group
+        else:
+            self.out_group = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if importance != None:
+            self.importance = importance
+        else:
+            self.importance = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if instructions != None:
+            self.instructions = instructions
+        else:
+            self.instructions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.cookie_mask))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append(util.pack_fm_cmd(self._command))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!L", self.out_group))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(struct.pack("!H", self.importance))
+        packed.append(self.match.pack())
+        packed.append(loxi.generic_util.pack_list(self.instructions))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_modify()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 14)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.cookie = reader.read("!Q")[0]
+        obj.cookie_mask = reader.read("!Q")[0]
+        obj.table_id = reader.read("!B")[0]
+        __command = util.unpack_fm_cmd(reader)
+        assert(__command == 1)
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.out_port = util.unpack_port_no(reader)
+        obj.out_group = reader.read("!L")[0]
+        obj.flags = reader.read("!H")[0]
+        obj.importance = reader.read("!H")[0]
+        obj.match = ofp.match.unpack(reader)
+        obj.instructions = loxi.generic_util.unpack_list(reader, ofp.instruction.instruction.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.cookie != other.cookie: return False
+        if self.cookie_mask != other.cookie_mask: return False
+        if self.table_id != other.table_id: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.priority != other.priority: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.out_port != other.out_port: return False
+        if self.out_group != other.out_group: return False
+        if self.flags != other.flags: return False
+        if self.importance != other.importance: return False
+        if self.match != other.match: return False
+        if self.instructions != other.instructions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_modify {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("cookie_mask = ");
+                q.text("%#x" % self.cookie_mask)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("out_group = ");
+                q.text("%#x" % self.out_group)
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("importance = ");
+                q.text("%#x" % self.importance)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("instructions = ");
+                q.pp(self.instructions)
+            q.breakable()
+        q.text('}')
+
+flow_mod.subtypes[1] = flow_modify
+
+class flow_modify_strict(flow_mod):
+    version = 5
+    type = 14
+    _command = 2
+
+    def __init__(self, xid=None, cookie=None, cookie_mask=None, table_id=None, idle_timeout=None, hard_timeout=None, priority=None, buffer_id=None, out_port=None, out_group=None, flags=None, importance=None, match=None, instructions=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if cookie_mask != None:
+            self.cookie_mask = cookie_mask
+        else:
+            self.cookie_mask = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if out_group != None:
+            self.out_group = out_group
+        else:
+            self.out_group = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if importance != None:
+            self.importance = importance
+        else:
+            self.importance = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if instructions != None:
+            self.instructions = instructions
+        else:
+            self.instructions = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.cookie_mask))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append(util.pack_fm_cmd(self._command))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!L", self.out_group))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(struct.pack("!H", self.importance))
+        packed.append(self.match.pack())
+        packed.append(loxi.generic_util.pack_list(self.instructions))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_modify_strict()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 14)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.cookie = reader.read("!Q")[0]
+        obj.cookie_mask = reader.read("!Q")[0]
+        obj.table_id = reader.read("!B")[0]
+        __command = util.unpack_fm_cmd(reader)
+        assert(__command == 2)
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.out_port = util.unpack_port_no(reader)
+        obj.out_group = reader.read("!L")[0]
+        obj.flags = reader.read("!H")[0]
+        obj.importance = reader.read("!H")[0]
+        obj.match = ofp.match.unpack(reader)
+        obj.instructions = loxi.generic_util.unpack_list(reader, ofp.instruction.instruction.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.cookie != other.cookie: return False
+        if self.cookie_mask != other.cookie_mask: return False
+        if self.table_id != other.table_id: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.priority != other.priority: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.out_port != other.out_port: return False
+        if self.out_group != other.out_group: return False
+        if self.flags != other.flags: return False
+        if self.importance != other.importance: return False
+        if self.match != other.match: return False
+        if self.instructions != other.instructions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_modify_strict {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("cookie_mask = ");
+                q.text("%#x" % self.cookie_mask)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("out_group = ");
+                q.text("%#x" % self.out_group)
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("importance = ");
+                q.text("%#x" % self.importance)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("instructions = ");
+                q.pp(self.instructions)
+            q.breakable()
+        q.text('}')
+
+flow_mod.subtypes[2] = flow_modify_strict
+
+class flow_monitor_failed_error_msg(error_msg):
+    version = 5
+    type = 1
+    err_type = 16
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_monitor_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 16)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_monitor_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[16] = flow_monitor_failed_error_msg
+
+class flow_removed(message):
+    version = 5
+    type = 11
+
+    def __init__(self, xid=None, cookie=None, priority=None, reason=None, table_id=None, duration_sec=None, duration_nsec=None, idle_timeout=None, hard_timeout=None, packet_count=None, byte_count=None, match=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if priority != None:
+            self.priority = priority
+        else:
+            self.priority = 0
+        if reason != None:
+            self.reason = reason
+        else:
+            self.reason = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if duration_sec != None:
+            self.duration_sec = duration_sec
+        else:
+            self.duration_sec = 0
+        if duration_nsec != None:
+            self.duration_nsec = duration_nsec
+        else:
+            self.duration_nsec = 0
+        if idle_timeout != None:
+            self.idle_timeout = idle_timeout
+        else:
+            self.idle_timeout = 0
+        if hard_timeout != None:
+            self.hard_timeout = hard_timeout
+        else:
+            self.hard_timeout = 0
+        if packet_count != None:
+            self.packet_count = packet_count
+        else:
+            self.packet_count = 0
+        if byte_count != None:
+            self.byte_count = byte_count
+        else:
+            self.byte_count = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!H", self.priority))
+        packed.append(struct.pack("!B", self.reason))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append(struct.pack("!L", self.duration_sec))
+        packed.append(struct.pack("!L", self.duration_nsec))
+        packed.append(struct.pack("!H", self.idle_timeout))
+        packed.append(struct.pack("!H", self.hard_timeout))
+        packed.append(struct.pack("!Q", self.packet_count))
+        packed.append(struct.pack("!Q", self.byte_count))
+        packed.append(self.match.pack())
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_removed()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 11)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.cookie = reader.read("!Q")[0]
+        obj.priority = reader.read("!H")[0]
+        obj.reason = reader.read("!B")[0]
+        obj.table_id = reader.read("!B")[0]
+        obj.duration_sec = reader.read("!L")[0]
+        obj.duration_nsec = reader.read("!L")[0]
+        obj.idle_timeout = reader.read("!H")[0]
+        obj.hard_timeout = reader.read("!H")[0]
+        obj.packet_count = reader.read("!Q")[0]
+        obj.byte_count = reader.read("!Q")[0]
+        obj.match = ofp.match.unpack(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.cookie != other.cookie: return False
+        if self.priority != other.priority: return False
+        if self.reason != other.reason: return False
+        if self.table_id != other.table_id: return False
+        if self.duration_sec != other.duration_sec: return False
+        if self.duration_nsec != other.duration_nsec: return False
+        if self.idle_timeout != other.idle_timeout: return False
+        if self.hard_timeout != other.hard_timeout: return False
+        if self.packet_count != other.packet_count: return False
+        if self.byte_count != other.byte_count: return False
+        if self.match != other.match: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_removed {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("priority = ");
+                q.text("%#x" % self.priority)
+                q.text(","); q.breakable()
+                q.text("reason = ");
+                q.text("%#x" % self.reason)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("duration_sec = ");
+                q.text("%#x" % self.duration_sec)
+                q.text(","); q.breakable()
+                q.text("duration_nsec = ");
+                q.text("%#x" % self.duration_nsec)
+                q.text(","); q.breakable()
+                q.text("idle_timeout = ");
+                q.text("%#x" % self.idle_timeout)
+                q.text(","); q.breakable()
+                q.text("hard_timeout = ");
+                q.text("%#x" % self.hard_timeout)
+                q.text(","); q.breakable()
+                q.text("packet_count = ");
+                q.text("%#x" % self.packet_count)
+                q.text(","); q.breakable()
+                q.text("byte_count = ");
+                q.text("%#x" % self.byte_count)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[11] = flow_removed
+
+class flow_stats_reply(stats_reply):
+    version = 5
+    type = 19
+    stats_type = 1
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 1)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.flow_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[1] = flow_stats_reply
+
+class flow_stats_request(stats_request):
+    version = 5
+    type = 18
+    stats_type = 1
+
+    def __init__(self, xid=None, flags=None, table_id=None, out_port=None, out_group=None, cookie=None, cookie_mask=None, match=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if out_port != None:
+            self.out_port = out_port
+        else:
+            self.out_port = 0
+        if out_group != None:
+            self.out_group = out_group
+        else:
+            self.out_group = 0
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if cookie_mask != None:
+            self.cookie_mask = cookie_mask
+        else:
+            self.cookie_mask = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append('\x00' * 3)
+        packed.append(util.pack_port_no(self.out_port))
+        packed.append(struct.pack("!L", self.out_group))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(struct.pack("!Q", self.cookie_mask))
+        packed.append(self.match.pack())
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = flow_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 1)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.table_id = reader.read("!B")[0]
+        reader.skip(3)
+        obj.out_port = util.unpack_port_no(reader)
+        obj.out_group = reader.read("!L")[0]
+        reader.skip(4)
+        obj.cookie = reader.read("!Q")[0]
+        obj.cookie_mask = reader.read("!Q")[0]
+        obj.match = ofp.match.unpack(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.table_id != other.table_id: return False
+        if self.out_port != other.out_port: return False
+        if self.out_group != other.out_group: return False
+        if self.cookie != other.cookie: return False
+        if self.cookie_mask != other.cookie_mask: return False
+        if self.match != other.match: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("flow_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("out_port = ");
+                q.text(util.pretty_port(self.out_port))
+                q.text(","); q.breakable()
+                q.text("out_group = ");
+                q.text("%#x" % self.out_group)
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("cookie_mask = ");
+                q.text("%#x" % self.cookie_mask)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[1] = flow_stats_request
+
+class get_config_reply(message):
+    version = 5
+    type = 8
+
+    def __init__(self, xid=None, flags=None, miss_send_len=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if miss_send_len != None:
+            self.miss_send_len = miss_send_len
+        else:
+            self.miss_send_len = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(struct.pack("!H", self.miss_send_len))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = get_config_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 8)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.flags = reader.read("!H")[0]
+        obj.miss_send_len = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.miss_send_len != other.miss_send_len: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("get_config_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("miss_send_len = ");
+                q.text("%#x" % self.miss_send_len)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[8] = get_config_reply
+
+class get_config_request(message):
+    version = 5
+    type = 7
+
+    def __init__(self, xid=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = get_config_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 7)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("get_config_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+message.subtypes[7] = get_config_request
+
+class group_mod(message):
+    subtypes = {}
+
+    version = 5
+    type = 15
+
+    def __init__(self, xid=None, command=None, group_type=None, group_id=None, buckets=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if command != None:
+            self.command = command
+        else:
+            self.command = 0
+        if group_type != None:
+            self.group_type = group_type
+        else:
+            self.group_type = 0
+        if group_id != None:
+            self.group_id = group_id
+        else:
+            self.group_id = 0
+        if buckets != None:
+            self.buckets = buckets
+        else:
+            self.buckets = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.command))
+        packed.append(struct.pack("!B", self.group_type))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!L", self.group_id))
+        packed.append(loxi.generic_util.pack_list(self.buckets))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 8)
+        subclass = group_mod.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = group_mod()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 15)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.command = reader.read("!H")[0]
+        obj.group_type = reader.read("!B")[0]
+        reader.skip(1)
+        obj.group_id = reader.read("!L")[0]
+        obj.buckets = loxi.generic_util.unpack_list(reader, ofp.common.bucket.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.command != other.command: return False
+        if self.group_type != other.group_type: return False
+        if self.group_id != other.group_id: return False
+        if self.buckets != other.buckets: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_mod {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("group_type = ");
+                q.text("%#x" % self.group_type)
+                q.text(","); q.breakable()
+                q.text("group_id = ");
+                q.text("%#x" % self.group_id)
+                q.text(","); q.breakable()
+                q.text("buckets = ");
+                q.pp(self.buckets)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[15] = group_mod
+
+class group_add(group_mod):
+    version = 5
+    type = 15
+    command = 0
+
+    def __init__(self, xid=None, group_type=None, group_id=None, buckets=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if group_type != None:
+            self.group_type = group_type
+        else:
+            self.group_type = 0
+        if group_id != None:
+            self.group_id = group_id
+        else:
+            self.group_id = 0
+        if buckets != None:
+            self.buckets = buckets
+        else:
+            self.buckets = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.command))
+        packed.append(struct.pack("!B", self.group_type))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!L", self.group_id))
+        packed.append(loxi.generic_util.pack_list(self.buckets))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_add()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 15)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _command = reader.read("!H")[0]
+        assert(_command == 0)
+        obj.group_type = reader.read("!B")[0]
+        reader.skip(1)
+        obj.group_id = reader.read("!L")[0]
+        obj.buckets = loxi.generic_util.unpack_list(reader, ofp.common.bucket.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.group_type != other.group_type: return False
+        if self.group_id != other.group_id: return False
+        if self.buckets != other.buckets: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_add {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("group_type = ");
+                q.text("%#x" % self.group_type)
+                q.text(","); q.breakable()
+                q.text("group_id = ");
+                q.text("%#x" % self.group_id)
+                q.text(","); q.breakable()
+                q.text("buckets = ");
+                q.pp(self.buckets)
+            q.breakable()
+        q.text('}')
+
+group_mod.subtypes[0] = group_add
+
+class group_delete(group_mod):
+    version = 5
+    type = 15
+    command = 2
+
+    def __init__(self, xid=None, group_type=None, group_id=None, buckets=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if group_type != None:
+            self.group_type = group_type
+        else:
+            self.group_type = 0
+        if group_id != None:
+            self.group_id = group_id
+        else:
+            self.group_id = 0
+        if buckets != None:
+            self.buckets = buckets
+        else:
+            self.buckets = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.command))
+        packed.append(struct.pack("!B", self.group_type))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!L", self.group_id))
+        packed.append(loxi.generic_util.pack_list(self.buckets))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_delete()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 15)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _command = reader.read("!H")[0]
+        assert(_command == 2)
+        obj.group_type = reader.read("!B")[0]
+        reader.skip(1)
+        obj.group_id = reader.read("!L")[0]
+        obj.buckets = loxi.generic_util.unpack_list(reader, ofp.common.bucket.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.group_type != other.group_type: return False
+        if self.group_id != other.group_id: return False
+        if self.buckets != other.buckets: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_delete {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("group_type = ");
+                q.text("%#x" % self.group_type)
+                q.text(","); q.breakable()
+                q.text("group_id = ");
+                q.text("%#x" % self.group_id)
+                q.text(","); q.breakable()
+                q.text("buckets = ");
+                q.pp(self.buckets)
+            q.breakable()
+        q.text('}')
+
+group_mod.subtypes[2] = group_delete
+
+class group_desc_stats_reply(stats_reply):
+    version = 5
+    type = 19
+    stats_type = 7
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_desc_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 7)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.group_desc_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_desc_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[7] = group_desc_stats_reply
+
+class group_desc_stats_request(stats_request):
+    version = 5
+    type = 18
+    stats_type = 7
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_desc_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 7)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_desc_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[7] = group_desc_stats_request
+
+class group_features_stats_reply(stats_reply):
+    version = 5
+    type = 19
+    stats_type = 8
+
+    def __init__(self, xid=None, flags=None, types=None, capabilities=None, max_groups_all=None, max_groups_select=None, max_groups_indirect=None, max_groups_ff=None, actions_all=None, actions_select=None, actions_indirect=None, actions_ff=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if types != None:
+            self.types = types
+        else:
+            self.types = 0
+        if capabilities != None:
+            self.capabilities = capabilities
+        else:
+            self.capabilities = 0
+        if max_groups_all != None:
+            self.max_groups_all = max_groups_all
+        else:
+            self.max_groups_all = 0
+        if max_groups_select != None:
+            self.max_groups_select = max_groups_select
+        else:
+            self.max_groups_select = 0
+        if max_groups_indirect != None:
+            self.max_groups_indirect = max_groups_indirect
+        else:
+            self.max_groups_indirect = 0
+        if max_groups_ff != None:
+            self.max_groups_ff = max_groups_ff
+        else:
+            self.max_groups_ff = 0
+        if actions_all != None:
+            self.actions_all = actions_all
+        else:
+            self.actions_all = 0
+        if actions_select != None:
+            self.actions_select = actions_select
+        else:
+            self.actions_select = 0
+        if actions_indirect != None:
+            self.actions_indirect = actions_indirect
+        else:
+            self.actions_indirect = 0
+        if actions_ff != None:
+            self.actions_ff = actions_ff
+        else:
+            self.actions_ff = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.types))
+        packed.append(struct.pack("!L", self.capabilities))
+        packed.append(struct.pack("!L", self.max_groups_all))
+        packed.append(struct.pack("!L", self.max_groups_select))
+        packed.append(struct.pack("!L", self.max_groups_indirect))
+        packed.append(struct.pack("!L", self.max_groups_ff))
+        packed.append(struct.pack("!L", self.actions_all))
+        packed.append(struct.pack("!L", self.actions_select))
+        packed.append(struct.pack("!L", self.actions_indirect))
+        packed.append(struct.pack("!L", self.actions_ff))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_features_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 8)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.types = reader.read("!L")[0]
+        obj.capabilities = reader.read("!L")[0]
+        obj.max_groups_all = reader.read("!L")[0]
+        obj.max_groups_select = reader.read("!L")[0]
+        obj.max_groups_indirect = reader.read("!L")[0]
+        obj.max_groups_ff = reader.read("!L")[0]
+        obj.actions_all = reader.read("!L")[0]
+        obj.actions_select = reader.read("!L")[0]
+        obj.actions_indirect = reader.read("!L")[0]
+        obj.actions_ff = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.types != other.types: return False
+        if self.capabilities != other.capabilities: return False
+        if self.max_groups_all != other.max_groups_all: return False
+        if self.max_groups_select != other.max_groups_select: return False
+        if self.max_groups_indirect != other.max_groups_indirect: return False
+        if self.max_groups_ff != other.max_groups_ff: return False
+        if self.actions_all != other.actions_all: return False
+        if self.actions_select != other.actions_select: return False
+        if self.actions_indirect != other.actions_indirect: return False
+        if self.actions_ff != other.actions_ff: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_features_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("types = ");
+                q.text("%#x" % self.types)
+                q.text(","); q.breakable()
+                q.text("capabilities = ");
+                q.text("%#x" % self.capabilities)
+                q.text(","); q.breakable()
+                q.text("max_groups_all = ");
+                q.text("%#x" % self.max_groups_all)
+                q.text(","); q.breakable()
+                q.text("max_groups_select = ");
+                q.text("%#x" % self.max_groups_select)
+                q.text(","); q.breakable()
+                q.text("max_groups_indirect = ");
+                q.text("%#x" % self.max_groups_indirect)
+                q.text(","); q.breakable()
+                q.text("max_groups_ff = ");
+                q.text("%#x" % self.max_groups_ff)
+                q.text(","); q.breakable()
+                q.text("actions_all = ");
+                q.text("%#x" % self.actions_all)
+                q.text(","); q.breakable()
+                q.text("actions_select = ");
+                q.text("%#x" % self.actions_select)
+                q.text(","); q.breakable()
+                q.text("actions_indirect = ");
+                q.text("%#x" % self.actions_indirect)
+                q.text(","); q.breakable()
+                q.text("actions_ff = ");
+                q.text("%#x" % self.actions_ff)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[8] = group_features_stats_reply
+
+class group_features_stats_request(stats_request):
+    version = 5
+    type = 18
+    stats_type = 8
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_features_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 8)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_features_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[8] = group_features_stats_request
+
+class group_mod_failed_error_msg(error_msg):
+    version = 5
+    type = 1
+    err_type = 6
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_mod_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 6)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_mod_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[6] = group_mod_failed_error_msg
+
+class group_modify(group_mod):
+    version = 5
+    type = 15
+    command = 1
+
+    def __init__(self, xid=None, group_type=None, group_id=None, buckets=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if group_type != None:
+            self.group_type = group_type
+        else:
+            self.group_type = 0
+        if group_id != None:
+            self.group_id = group_id
+        else:
+            self.group_id = 0
+        if buckets != None:
+            self.buckets = buckets
+        else:
+            self.buckets = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.command))
+        packed.append(struct.pack("!B", self.group_type))
+        packed.append('\x00' * 1)
+        packed.append(struct.pack("!L", self.group_id))
+        packed.append(loxi.generic_util.pack_list(self.buckets))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_modify()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 15)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _command = reader.read("!H")[0]
+        assert(_command == 1)
+        obj.group_type = reader.read("!B")[0]
+        reader.skip(1)
+        obj.group_id = reader.read("!L")[0]
+        obj.buckets = loxi.generic_util.unpack_list(reader, ofp.common.bucket.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.group_type != other.group_type: return False
+        if self.group_id != other.group_id: return False
+        if self.buckets != other.buckets: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_modify {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("group_type = ");
+                q.text("%#x" % self.group_type)
+                q.text(","); q.breakable()
+                q.text("group_id = ");
+                q.text("%#x" % self.group_id)
+                q.text(","); q.breakable()
+                q.text("buckets = ");
+                q.pp(self.buckets)
+            q.breakable()
+        q.text('}')
+
+group_mod.subtypes[1] = group_modify
+
+class group_stats_reply(stats_reply):
+    version = 5
+    type = 19
+    stats_type = 6
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 6)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.group_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[6] = group_stats_reply
+
+class group_stats_request(stats_request):
+    version = 5
+    type = 18
+    stats_type = 6
+
+    def __init__(self, xid=None, flags=None, group_id=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if group_id != None:
+            self.group_id = group_id
+        else:
+            self.group_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.group_id))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = group_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 6)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.group_id = reader.read("!L")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.group_id != other.group_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("group_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("group_id = ");
+                q.text("%#x" % self.group_id)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[6] = group_stats_request
+
+class hello(message):
+    version = 5
+    type = 0
+
+    def __init__(self, xid=None, elements=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if elements != None:
+            self.elements = elements
+        else:
+            self.elements = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(loxi.generic_util.pack_list(self.elements))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = hello()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 0)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.elements = loxi.generic_util.unpack_list(reader, ofp.common.hello_elem.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.elements != other.elements: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("hello {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("elements = ");
+                q.pp(self.elements)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[0] = hello
+
+class hello_failed_error_msg(error_msg):
+    version = 5
+    type = 1
+    err_type = 0
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = hello_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 0)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("hello_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[0] = hello_failed_error_msg
+
+class meter_config_stats_reply(stats_reply):
+    version = 5
+    type = 19
+    stats_type = 10
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = meter_config_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 10)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.meter_band.meter_band.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("meter_config_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[10] = meter_config_stats_reply
+
+class meter_config_stats_request(stats_request):
+    version = 5
+    type = 18
+    stats_type = 10
+
+    def __init__(self, xid=None, flags=None, meter_id=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if meter_id != None:
+            self.meter_id = meter_id
+        else:
+            self.meter_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.meter_id))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = meter_config_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 10)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.meter_id = reader.read("!L")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.meter_id != other.meter_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("meter_config_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("meter_id = ");
+                q.text("%#x" % self.meter_id)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[10] = meter_config_stats_request
+
+class meter_features_stats_reply(stats_reply):
+    version = 5
+    type = 19
+    stats_type = 11
+
+    def __init__(self, xid=None, flags=None, features=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if features != None:
+            self.features = features
+        else:
+            self.features = ofp.meter_features()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(self.features.pack())
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = meter_features_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 11)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.features = ofp.meter_features.unpack(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.features != other.features: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("meter_features_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("features = ");
+                q.pp(self.features)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[11] = meter_features_stats_reply
+
+class meter_features_stats_request(stats_request):
+    version = 5
+    type = 18
+    stats_type = 11
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = meter_features_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 11)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("meter_features_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[11] = meter_features_stats_request
+
+class meter_mod(message):
+    version = 5
+    type = 29
+
+    def __init__(self, xid=None, command=None, flags=None, meter_id=None, bands=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if command != None:
+            self.command = command
+        else:
+            self.command = 0
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if meter_id != None:
+            self.meter_id = meter_id
+        else:
+            self.meter_id = 0
+        if bands != None:
+            self.bands = bands
+        else:
+            self.bands = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.command))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(struct.pack("!L", self.meter_id))
+        packed.append(loxi.generic_util.pack_list(self.bands))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = meter_mod()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 29)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.command = reader.read("!H")[0]
+        obj.flags = reader.read("!H")[0]
+        obj.meter_id = reader.read("!L")[0]
+        obj.bands = loxi.generic_util.unpack_list(reader, ofp.meter_band.meter_band.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.command != other.command: return False
+        if self.flags != other.flags: return False
+        if self.meter_id != other.meter_id: return False
+        if self.bands != other.bands: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("meter_mod {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("command = ");
+                q.text("%#x" % self.command)
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("meter_id = ");
+                q.text("%#x" % self.meter_id)
+                q.text(","); q.breakable()
+                q.text("bands = ");
+                q.pp(self.bands)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[29] = meter_mod
+
+class meter_mod_failed_error_msg(error_msg):
+    version = 5
+    type = 1
+    err_type = 12
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = meter_mod_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 12)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("meter_mod_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[12] = meter_mod_failed_error_msg
+
+class meter_stats_reply(stats_reply):
+    version = 5
+    type = 19
+    stats_type = 9
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = meter_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 9)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.meter_stats.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("meter_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[9] = meter_stats_reply
+
+class meter_stats_request(stats_request):
+    version = 5
+    type = 18
+    stats_type = 9
+
+    def __init__(self, xid=None, flags=None, meter_id=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if meter_id != None:
+            self.meter_id = meter_id
+        else:
+            self.meter_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.meter_id))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = meter_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 9)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.meter_id = reader.read("!L")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.meter_id != other.meter_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("meter_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("meter_id = ");
+                q.text("%#x" % self.meter_id)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[9] = meter_stats_request
+
+class nicira_header(experimenter):
+    subtypes = {}
+
+    version = 5
+    type = 4
+    experimenter = 8992
+
+    def __init__(self, xid=None, subtype=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if subtype != None:
+            self.subtype = subtype
+        else:
+            self.subtype = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.subtype))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 12)
+        subclass = nicira_header.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = nicira_header()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 4)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 8992)
+        obj.subtype = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.subtype != other.subtype: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("nicira_header {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+            q.breakable()
+        q.text('}')
+
+experimenter.subtypes[8992] = nicira_header
+
+class packet_in(message):
+    version = 5
+    type = 10
+
+    def __init__(self, xid=None, buffer_id=None, total_len=None, reason=None, table_id=None, cookie=None, match=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if total_len != None:
+            self.total_len = total_len
+        else:
+            self.total_len = 0
+        if reason != None:
+            self.reason = reason
+        else:
+            self.reason = 0
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if cookie != None:
+            self.cookie = cookie
+        else:
+            self.cookie = 0
+        if match != None:
+            self.match = match
+        else:
+            self.match = ofp.match()
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(struct.pack("!H", self.total_len))
+        packed.append(struct.pack("!B", self.reason))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append(struct.pack("!Q", self.cookie))
+        packed.append(self.match.pack())
+        packed.append('\x00' * 2)
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = packet_in()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 10)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.total_len = reader.read("!H")[0]
+        obj.reason = reader.read("!B")[0]
+        obj.table_id = reader.read("!B")[0]
+        obj.cookie = reader.read("!Q")[0]
+        obj.match = ofp.match.unpack(reader)
+        reader.skip(2)
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.total_len != other.total_len: return False
+        if self.reason != other.reason: return False
+        if self.table_id != other.table_id: return False
+        if self.cookie != other.cookie: return False
+        if self.match != other.match: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("packet_in {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("total_len = ");
+                q.text("%#x" % self.total_len)
+                q.text(","); q.breakable()
+                q.text("reason = ");
+                q.text("%#x" % self.reason)
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("cookie = ");
+                q.text("%#x" % self.cookie)
+                q.text(","); q.breakable()
+                q.text("match = ");
+                q.pp(self.match)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[10] = packet_in
+
+class packet_out(message):
+    version = 5
+    type = 13
+
+    def __init__(self, xid=None, buffer_id=None, in_port=None, actions=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if buffer_id != None:
+            self.buffer_id = buffer_id
+        else:
+            self.buffer_id = 0
+        if in_port != None:
+            self.in_port = in_port
+        else:
+            self.in_port = 0
+        if actions != None:
+            self.actions = actions
+        else:
+            self.actions = []
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.buffer_id))
+        packed.append(util.pack_port_no(self.in_port))
+        packed.append(struct.pack("!H", 0)) # placeholder for actions_len at index 6
+        packed.append('\x00' * 6)
+        packed.append(loxi.generic_util.pack_list(self.actions))
+        packed[6] = struct.pack("!H", len(packed[-1]))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = packet_out()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 13)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.buffer_id = reader.read("!L")[0]
+        obj.in_port = util.unpack_port_no(reader)
+        _actions_len = reader.read("!H")[0]
+        reader.skip(6)
+        obj.actions = loxi.generic_util.unpack_list(reader.slice(_actions_len), ofp.action.action.unpack)
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.buffer_id != other.buffer_id: return False
+        if self.in_port != other.in_port: return False
+        if self.actions != other.actions: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("packet_out {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("buffer_id = ");
+                q.text("%#x" % self.buffer_id)
+                q.text(","); q.breakable()
+                q.text("in_port = ");
+                q.text(util.pretty_port(self.in_port))
+                q.text(","); q.breakable()
+                q.text("actions = ");
+                q.pp(self.actions)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[13] = packet_out
+
+class port_desc_stats_reply(stats_reply):
+    version = 5
+    type = 19
+    stats_type = 13
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_desc_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 13)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.port_desc.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_desc_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[13] = port_desc_stats_reply
+
+class port_desc_stats_request(stats_request):
+    version = 5
+    type = 18
+    stats_type = 13
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_desc_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 13)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_desc_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[13] = port_desc_stats_request
+
+class port_mod(message):
+    version = 5
+    type = 16
+
+    def __init__(self, xid=None, port_no=None, hw_addr=None, config=None, mask=None, properties=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if hw_addr != None:
+            self.hw_addr = hw_addr
+        else:
+            self.hw_addr = [0,0,0,0,0,0]
+        if config != None:
+            self.config = config
+        else:
+            self.config = 0
+        if mask != None:
+            self.mask = mask
+        else:
+            self.mask = 0
+        if properties != None:
+            self.properties = properties
+        else:
+            self.properties = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!6B", *self.hw_addr))
+        packed.append('\x00' * 2)
+        packed.append(struct.pack("!L", self.config))
+        packed.append(struct.pack("!L", self.mask))
+        packed.append(loxi.generic_util.pack_list(self.properties))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_mod()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 16)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.port_no = util.unpack_port_no(reader)
+        reader.skip(4)
+        obj.hw_addr = list(reader.read('!6B'))
+        reader.skip(2)
+        obj.config = reader.read("!L")[0]
+        obj.mask = reader.read("!L")[0]
+        obj.properties = loxi.generic_util.unpack_list(reader, ofp.port_mod_prop.port_mod_prop.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.port_no != other.port_no: return False
+        if self.hw_addr != other.hw_addr: return False
+        if self.config != other.config: return False
+        if self.mask != other.mask: return False
+        if self.properties != other.properties: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_mod {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("hw_addr = ");
+                q.text(util.pretty_mac(self.hw_addr))
+                q.text(","); q.breakable()
+                q.text("config = ");
+                q.text("%#x" % self.config)
+                q.text(","); q.breakable()
+                q.text("mask = ");
+                q.text("%#x" % self.mask)
+                q.text(","); q.breakable()
+                q.text("properties = ");
+                q.pp(self.properties)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[16] = port_mod
+
+class port_mod_failed_error_msg(error_msg):
+    version = 5
+    type = 1
+    err_type = 7
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_mod_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 7)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_mod_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[7] = port_mod_failed_error_msg
+
+class port_stats_reply(stats_reply):
+    version = 5
+    type = 19
+    stats_type = 4
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 4)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.port_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[4] = port_stats_reply
+
+class port_stats_request(stats_request):
+    version = 5
+    type = 18
+    stats_type = 4
+
+    def __init__(self, xid=None, flags=None, port_no=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 4)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.port_no = util.unpack_port_no(reader)
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.port_no != other.port_no: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[4] = port_stats_request
+
+class port_status(message):
+    version = 5
+    type = 12
+
+    def __init__(self, xid=None, reason=None, desc=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if reason != None:
+            self.reason = reason
+        else:
+            self.reason = 0
+        if desc != None:
+            self.desc = desc
+        else:
+            self.desc = ofp.port_desc()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!B", self.reason))
+        packed.append('\x00' * 7)
+        packed.append(self.desc.pack())
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = port_status()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 12)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.reason = reader.read("!B")[0]
+        reader.skip(7)
+        obj.desc = ofp.port_desc.unpack(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.reason != other.reason: return False
+        if self.desc != other.desc: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_status {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("reason = ");
+                q.text("%#x" % self.reason)
+                q.text(","); q.breakable()
+                q.text("desc = ");
+                q.pp(self.desc)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[12] = port_status
+
+class queue_desc_stats_reply(stats_reply):
+    version = 5
+    type = 19
+    stats_type = 15
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_desc_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 15)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.queue_desc.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_desc_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[15] = queue_desc_stats_reply
+
+class queue_desc_stats_request(stats_request):
+    version = 5
+    type = 18
+    stats_type = 15
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_desc_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 15)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_desc_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[15] = queue_desc_stats_request
+
+class queue_op_failed_error_msg(error_msg):
+    version = 5
+    type = 1
+    err_type = 9
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_op_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 9)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_op_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[9] = queue_op_failed_error_msg
+
+class queue_stats_reply(stats_reply):
+    version = 5
+    type = 19
+    stats_type = 5
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 5)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.queue_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[5] = queue_stats_reply
+
+class queue_stats_request(stats_request):
+    version = 5
+    type = 18
+    stats_type = 5
+
+    def __init__(self, xid=None, flags=None, port_no=None, queue_id=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if port_no != None:
+            self.port_no = port_no
+        else:
+            self.port_no = 0
+        if queue_id != None:
+            self.queue_id = queue_id
+        else:
+            self.queue_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(util.pack_port_no(self.port_no))
+        packed.append(struct.pack("!L", self.queue_id))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = queue_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 5)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.port_no = util.unpack_port_no(reader)
+        obj.queue_id = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.port_no != other.port_no: return False
+        if self.queue_id != other.queue_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("port_no = ");
+                q.text(util.pretty_port(self.port_no))
+                q.text(","); q.breakable()
+                q.text("queue_id = ");
+                q.text("%#x" % self.queue_id)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[5] = queue_stats_request
+
+class requestforward(message):
+    version = 5
+    type = 32
+
+    def __init__(self, xid=None, role=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if role != None:
+            self.role = role
+        else:
+            self.role = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.role))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = requestforward()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 32)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.role = reader.read("!L")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.role != other.role: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("requestforward {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("role = ");
+                q.text("%#x" % self.role)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[32] = requestforward
+
+class role_reply(message):
+    version = 5
+    type = 25
+
+    def __init__(self, xid=None, role=None, generation_id=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if role != None:
+            self.role = role
+        else:
+            self.role = 0
+        if generation_id != None:
+            self.generation_id = generation_id
+        else:
+            self.generation_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.role))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!Q", self.generation_id))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = role_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 25)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.role = reader.read("!L")[0]
+        reader.skip(4)
+        obj.generation_id = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.role != other.role: return False
+        if self.generation_id != other.generation_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("role_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("role = ");
+                q.text("%#x" % self.role)
+                q.text(","); q.breakable()
+                q.text("generation_id = ");
+                q.text("%#x" % self.generation_id)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[25] = role_reply
+
+class role_request(message):
+    version = 5
+    type = 24
+
+    def __init__(self, xid=None, role=None, generation_id=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if role != None:
+            self.role = role
+        else:
+            self.role = 0
+        if generation_id != None:
+            self.generation_id = generation_id
+        else:
+            self.generation_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.role))
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!Q", self.generation_id))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = role_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 24)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.role = reader.read("!L")[0]
+        reader.skip(4)
+        obj.generation_id = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.role != other.role: return False
+        if self.generation_id != other.generation_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("role_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("role = ");
+                q.text("%#x" % self.role)
+                q.text(","); q.breakable()
+                q.text("generation_id = ");
+                q.text("%#x" % self.generation_id)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[24] = role_request
+
+class role_request_failed_error_msg(error_msg):
+    version = 5
+    type = 1
+    err_type = 11
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = role_request_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 11)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("role_request_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[11] = role_request_failed_error_msg
+
+class role_status(message):
+    version = 5
+    type = 30
+
+    def __init__(self, xid=None, role=None, reason=None, generation_id=None, properties=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if role != None:
+            self.role = role
+        else:
+            self.role = 0
+        if reason != None:
+            self.reason = reason
+        else:
+            self.reason = 0
+        if generation_id != None:
+            self.generation_id = generation_id
+        else:
+            self.generation_id = 0
+        if properties != None:
+            self.properties = properties
+        else:
+            self.properties = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.role))
+        packed.append(struct.pack("!B", self.reason))
+        packed.append('\x00' * 3)
+        packed.append(struct.pack("!Q", self.generation_id))
+        packed.append(loxi.generic_util.pack_list(self.properties))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = role_status()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 30)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.role = reader.read("!L")[0]
+        obj.reason = reader.read("!B")[0]
+        reader.skip(3)
+        obj.generation_id = reader.read("!Q")[0]
+        obj.properties = loxi.generic_util.unpack_list(reader, ofp.role_prop.role_prop.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.role != other.role: return False
+        if self.reason != other.reason: return False
+        if self.generation_id != other.generation_id: return False
+        if self.properties != other.properties: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("role_status {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("role = ");
+                q.text("%#x" % self.role)
+                q.text(","); q.breakable()
+                q.text("reason = ");
+                q.text("%#x" % self.reason)
+                q.text(","); q.breakable()
+                q.text("generation_id = ");
+                q.text("%#x" % self.generation_id)
+                q.text(","); q.breakable()
+                q.text("properties = ");
+                q.pp(self.properties)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[30] = role_status
+
+class set_config(message):
+    version = 5
+    type = 9
+
+    def __init__(self, xid=None, flags=None, miss_send_len=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if miss_send_len != None:
+            self.miss_send_len = miss_send_len
+        else:
+            self.miss_send_len = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append(struct.pack("!H", self.miss_send_len))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = set_config()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 9)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.flags = reader.read("!H")[0]
+        obj.miss_send_len = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.miss_send_len != other.miss_send_len: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("set_config {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("miss_send_len = ");
+                q.text("%#x" % self.miss_send_len)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[9] = set_config
+
+class switch_config_failed_error_msg(error_msg):
+    version = 5
+    type = 1
+    err_type = 10
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = switch_config_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 10)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("switch_config_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[10] = switch_config_failed_error_msg
+
+class table_desc_stats_reply(stats_reply):
+    version = 5
+    type = 19
+    stats_type = 14
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_desc_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 14)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.table_desc.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_desc_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[14] = table_desc_stats_reply
+
+class table_desc_stats_request(stats_request):
+    version = 5
+    type = 18
+    stats_type = 14
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_desc_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 14)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_desc_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[14] = table_desc_stats_request
+
+class table_features_failed_error_msg(error_msg):
+    version = 5
+    type = 1
+    err_type = 13
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_features_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 13)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_features_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[13] = table_features_failed_error_msg
+
+class table_features_stats_reply(stats_reply):
+    version = 5
+    type = 19
+    stats_type = 12
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_features_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 12)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.table_features.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_features_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[12] = table_features_stats_reply
+
+class table_features_stats_request(stats_request):
+    version = 5
+    type = 18
+    stats_type = 12
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_features_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 12)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.table_features.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_features_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[12] = table_features_stats_request
+
+class table_mod(message):
+    version = 5
+    type = 17
+
+    def __init__(self, xid=None, table_id=None, config=None, properties=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if table_id != None:
+            self.table_id = table_id
+        else:
+            self.table_id = 0
+        if config != None:
+            self.config = config
+        else:
+            self.config = 0
+        if properties != None:
+            self.properties = properties
+        else:
+            self.properties = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!B", self.table_id))
+        packed.append('\x00' * 3)
+        packed.append(struct.pack("!L", self.config))
+        packed.append(loxi.generic_util.pack_list(self.properties))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_mod()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 17)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.table_id = reader.read("!B")[0]
+        reader.skip(3)
+        obj.config = reader.read("!L")[0]
+        obj.properties = loxi.generic_util.unpack_list(reader, ofp.table_mod_prop.table_mod_prop.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.table_id != other.table_id: return False
+        if self.config != other.config: return False
+        if self.properties != other.properties: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_mod {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("table_id = ");
+                q.text("%#x" % self.table_id)
+                q.text(","); q.breakable()
+                q.text("config = ");
+                q.text("%#x" % self.config)
+                q.text(","); q.breakable()
+                q.text("properties = ");
+                q.pp(self.properties)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[17] = table_mod
+
+class table_mod_failed_error_msg(error_msg):
+    version = 5
+    type = 1
+    err_type = 8
+
+    def __init__(self, xid=None, code=None, data=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if code != None:
+            self.code = code
+        else:
+            self.code = 0
+        if data != None:
+            self.data = data
+        else:
+            self.data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.err_type))
+        packed.append(struct.pack("!H", self.code))
+        packed.append(self.data)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_mod_failed_error_msg()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _err_type = reader.read("!H")[0]
+        assert(_err_type == 8)
+        obj.code = reader.read("!H")[0]
+        obj.data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.code != other.code: return False
+        if self.data != other.data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_mod_failed_error_msg {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("code = ");
+                q.text("%#x" % self.code)
+                q.text(","); q.breakable()
+                q.text("data = ");
+                q.pp(self.data)
+            q.breakable()
+        q.text('}')
+
+error_msg.subtypes[8] = table_mod_failed_error_msg
+
+class table_stats_reply(stats_reply):
+    version = 5
+    type = 19
+    stats_type = 3
+
+    def __init__(self, xid=None, flags=None, entries=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if entries != None:
+            self.entries = entries
+        else:
+            self.entries = []
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        packed.append(loxi.generic_util.pack_list(self.entries))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_stats_reply()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 19)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 3)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        obj.entries = loxi.generic_util.unpack_list(reader, ofp.common.table_stats_entry.unpack)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        if self.entries != other.entries: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_stats_reply {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("entries = ");
+                q.pp(self.entries)
+            q.breakable()
+        q.text('}')
+
+stats_reply.subtypes[3] = table_stats_reply
+
+class table_stats_request(stats_request):
+    version = 5
+    type = 18
+    stats_type = 3
+
+    def __init__(self, xid=None, flags=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!H", self.stats_type))
+        packed.append(struct.pack("!H", self.flags))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_stats_request()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 18)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        _stats_type = reader.read("!H")[0]
+        assert(_stats_type == 3)
+        obj.flags = reader.read("!H")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.flags != other.flags: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_stats_request {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+            q.breakable()
+        q.text('}')
+
+stats_request.subtypes[3] = table_stats_request
+
+class table_status(message):
+    version = 5
+    type = 31
+
+    def __init__(self, xid=None, role=None, reason=None, table=None):
+        if xid != None:
+            self.xid = xid
+        else:
+            self.xid = None
+        if role != None:
+            self.role = role
+        else:
+            self.role = 0
+        if reason != None:
+            self.reason = reason
+        else:
+            self.reason = 0
+        if table != None:
+            self.table = table
+        else:
+            self.table = ofp.table_desc()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        packed.append(struct.pack("!L", self.role))
+        packed.append(struct.pack("!B", self.reason))
+        packed.append('\x00' * 7)
+        packed.append(self.table.pack())
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = table_status()
+        _version = reader.read("!B")[0]
+        assert(_version == 5)
+        _type = reader.read("!B")[0]
+        assert(_type == 31)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.xid = reader.read("!L")[0]
+        obj.role = reader.read("!L")[0]
+        obj.reason = reader.read("!B")[0]
+        reader.skip(7)
+        obj.table = ofp.table_desc.unpack(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.xid != other.xid: return False
+        if self.role != other.role: return False
+        if self.reason != other.reason: return False
+        if self.table != other.table: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_status {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("xid = ");
+                if self.xid != None:
+                    q.text("%#x" % self.xid)
+                else:
+                    q.text('None')
+                q.text(","); q.breakable()
+                q.text("role = ");
+                q.text("%#x" % self.role)
+                q.text(","); q.breakable()
+                q.text("reason = ");
+                q.text("%#x" % self.reason)
+                q.text(","); q.breakable()
+                q.text("table = ");
+                q.pp(self.table)
+            q.breakable()
+        q.text('}')
+
+message.subtypes[31] = table_status
+
+
+def parse_header(buf):
+    if len(buf) < 8:
+        raise loxi.ProtocolError("too short to be an OpenFlow message")
+    return struct.unpack_from("!BBHL", buf)
+
+def parse_message(buf):
+    msg_ver, msg_type, msg_len, msg_xid = parse_header(buf)
+    if msg_ver != ofp.OFP_VERSION and msg_type != ofp.OFPT_HELLO:
+        raise loxi.ProtocolError("wrong OpenFlow version (expected %d, got %d)" % (ofp.OFP_VERSION, msg_ver))
+    if len(buf) != msg_len:
+        raise loxi.ProtocolError("incorrect message size")
+    return message.unpack(loxi.generic_util.OFReader(buf))
diff --git a/Fabric/Utilities/src/python/loxi/of14/meter_band.py b/Fabric/Utilities/src/python/loxi/of14/meter_band.py
new file mode 100644
index 0000000..c676cf0
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of14/meter_band.py
@@ -0,0 +1,275 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of14']
+
+class meter_band(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = meter_band.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = meter_band()
+        obj.type = reader.read("!H")[0]
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("meter_band {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class drop(meter_band):
+    type = 1
+
+    def __init__(self, rate=None, burst_size=None):
+        if rate != None:
+            self.rate = rate
+        else:
+            self.rate = 0
+        if burst_size != None:
+            self.burst_size = burst_size
+        else:
+            self.burst_size = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.rate))
+        packed.append(struct.pack("!L", self.burst_size))
+        packed.append('\x00' * 4)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = drop()
+        _type = reader.read("!H")[0]
+        assert(_type == 1)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.rate = reader.read("!L")[0]
+        obj.burst_size = reader.read("!L")[0]
+        reader.skip(4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.rate != other.rate: return False
+        if self.burst_size != other.burst_size: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("drop {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("rate = ");
+                q.text("%#x" % self.rate)
+                q.text(","); q.breakable()
+                q.text("burst_size = ");
+                q.text("%#x" % self.burst_size)
+            q.breakable()
+        q.text('}')
+
+meter_band.subtypes[1] = drop
+
+class dscp_remark(meter_band):
+    type = 2
+
+    def __init__(self, rate=None, burst_size=None, prec_level=None):
+        if rate != None:
+            self.rate = rate
+        else:
+            self.rate = 0
+        if burst_size != None:
+            self.burst_size = burst_size
+        else:
+            self.burst_size = 0
+        if prec_level != None:
+            self.prec_level = prec_level
+        else:
+            self.prec_level = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.rate))
+        packed.append(struct.pack("!L", self.burst_size))
+        packed.append(struct.pack("!B", self.prec_level))
+        packed.append('\x00' * 3)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = dscp_remark()
+        _type = reader.read("!H")[0]
+        assert(_type == 2)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.rate = reader.read("!L")[0]
+        obj.burst_size = reader.read("!L")[0]
+        obj.prec_level = reader.read("!B")[0]
+        reader.skip(3)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.rate != other.rate: return False
+        if self.burst_size != other.burst_size: return False
+        if self.prec_level != other.prec_level: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("dscp_remark {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("rate = ");
+                q.text("%#x" % self.rate)
+                q.text(","); q.breakable()
+                q.text("burst_size = ");
+                q.text("%#x" % self.burst_size)
+                q.text(","); q.breakable()
+                q.text("prec_level = ");
+                q.text("%#x" % self.prec_level)
+            q.breakable()
+        q.text('}')
+
+meter_band.subtypes[2] = dscp_remark
+
+class experimenter(meter_band):
+    type = 65535
+
+    def __init__(self, rate=None, burst_size=None, experimenter=None):
+        if rate != None:
+            self.rate = rate
+        else:
+            self.rate = 0
+        if burst_size != None:
+            self.burst_size = burst_size
+        else:
+            self.burst_size = 0
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
+        packed.append(struct.pack("!L", self.rate))
+        packed.append(struct.pack("!L", self.burst_size))
+        packed.append(struct.pack("!L", self.experimenter))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = experimenter()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len, 4)
+        obj.rate = reader.read("!L")[0]
+        obj.burst_size = reader.read("!L")[0]
+        obj.experimenter = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.rate != other.rate: return False
+        if self.burst_size != other.burst_size: return False
+        if self.experimenter != other.experimenter: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("rate = ");
+                q.text("%#x" % self.rate)
+                q.text(","); q.breakable()
+                q.text("burst_size = ");
+                q.text("%#x" % self.burst_size)
+                q.text(","); q.breakable()
+                q.text("experimenter = ");
+                q.text("%#x" % self.experimenter)
+            q.breakable()
+        q.text('}')
+
+meter_band.subtypes[65535] = experimenter
+
+
diff --git a/Fabric/Utilities/src/python/loxi/of14/oxm.py b/Fabric/Utilities/src/python/loxi/of14/oxm.py
new file mode 100644
index 0000000..88e1fce
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of14/oxm.py
@@ -0,0 +1,5962 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of14']
+
+class oxm(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type_len=None):
+        if type_len != None:
+            self.type_len = type_len
+        else:
+            self.type_len = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 0)
+        subclass = oxm.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = oxm()
+        obj.type_len = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type_len != other.type_len: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("oxm {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class arp_op(oxm):
+    type_len = 2147494402
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = arp_op()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147494402)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("arp_op {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147494402] = arp_op
+
+class arp_op_masked(oxm):
+    type_len = 2147494660
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        packed.append(struct.pack("!H", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = arp_op_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147494660)
+        obj.value = reader.read("!H")[0]
+        obj.value_mask = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("arp_op_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147494660] = arp_op_masked
+
+class arp_sha(oxm):
+    type_len = 2147495942
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = arp_sha()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147495942)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("arp_sha {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147495942] = arp_sha
+
+class arp_sha_masked(oxm):
+    type_len = 2147496204
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        packed.append(struct.pack("!6B", *self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = arp_sha_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147496204)
+        obj.value = list(reader.read('!6B'))
+        obj.value_mask = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("arp_sha_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_mac(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147496204] = arp_sha_masked
+
+class arp_spa(oxm):
+    type_len = 2147494916
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = arp_spa()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147494916)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("arp_spa {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147494916] = arp_spa
+
+class arp_spa_masked(oxm):
+    type_len = 2147495176
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = arp_spa_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147495176)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("arp_spa_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147495176] = arp_spa_masked
+
+class arp_tha(oxm):
+    type_len = 2147496454
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = arp_tha()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147496454)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("arp_tha {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147496454] = arp_tha
+
+class arp_tha_masked(oxm):
+    type_len = 2147496716
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        packed.append(struct.pack("!6B", *self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = arp_tha_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147496716)
+        obj.value = list(reader.read('!6B'))
+        obj.value_mask = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("arp_tha_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_mac(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147496716] = arp_tha_masked
+
+class arp_tpa(oxm):
+    type_len = 2147495428
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = arp_tpa()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147495428)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("arp_tpa {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147495428] = arp_tpa
+
+class arp_tpa_masked(oxm):
+    type_len = 2147495688
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = arp_tpa_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147495688)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("arp_tpa_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147495688] = arp_tpa_masked
+
+class bsn_egr_port_group_id(oxm):
+    type_len = 200196
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_egr_port_group_id()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 200196)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_egr_port_group_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[200196] = bsn_egr_port_group_id
+
+class bsn_egr_port_group_id_masked(oxm):
+    type_len = 200456
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_egr_port_group_id_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 200456)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_egr_port_group_id_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[200456] = bsn_egr_port_group_id_masked
+
+class bsn_in_ports_128(oxm):
+    type_len = 196624
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = set()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(util.pack_bitmap_128(self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_in_ports_128()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 196624)
+        obj.value = util.unpack_bitmap_128(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_in_ports_128 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[196624] = bsn_in_ports_128
+
+class bsn_in_ports_128_masked(oxm):
+    type_len = 196896
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = set()
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = set()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(util.pack_bitmap_128(self.value))
+        packed.append(util.pack_bitmap_128(self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_in_ports_128_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 196896)
+        obj.value = util.unpack_bitmap_128(reader)
+        obj.value_mask = util.unpack_bitmap_128(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_in_ports_128_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.pp(self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[196896] = bsn_in_ports_128_masked
+
+class bsn_in_ports_512(oxm):
+    type_len = 206400
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = set()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(util.pack_bitmap_512(self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_in_ports_512()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 206400)
+        obj.value = util.unpack_bitmap_512(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_in_ports_512 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[206400] = bsn_in_ports_512
+
+class bsn_in_ports_512_masked(oxm):
+    type_len = 206720
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = set()
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = set()
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(util.pack_bitmap_512(self.value))
+        packed.append(util.pack_bitmap_512(self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_in_ports_512_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 206720)
+        obj.value = util.unpack_bitmap_512(reader)
+        obj.value_mask = util.unpack_bitmap_512(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_in_ports_512_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.pp(self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[206720] = bsn_in_ports_512_masked
+
+class bsn_ingress_port_group_id(oxm):
+    type_len = 206852
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_ingress_port_group_id()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 206852)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_ingress_port_group_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[206852] = bsn_ingress_port_group_id
+
+class bsn_ingress_port_group_id_masked(oxm):
+    type_len = 207112
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_ingress_port_group_id_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 207112)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_ingress_port_group_id_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[207112] = bsn_ingress_port_group_id_masked
+
+class bsn_inner_eth_dst(oxm):
+    type_len = 207878
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_inner_eth_dst()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 207878)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_inner_eth_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[207878] = bsn_inner_eth_dst
+
+class bsn_inner_eth_dst_masked(oxm):
+    type_len = 208140
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        packed.append(struct.pack("!6B", *self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_inner_eth_dst_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 208140)
+        obj.value = list(reader.read('!6B'))
+        obj.value_mask = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_inner_eth_dst_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_mac(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[208140] = bsn_inner_eth_dst_masked
+
+class bsn_inner_eth_src(oxm):
+    type_len = 208390
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_inner_eth_src()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 208390)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_inner_eth_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[208390] = bsn_inner_eth_src
+
+class bsn_inner_eth_src_masked(oxm):
+    type_len = 208652
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        packed.append(struct.pack("!6B", *self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_inner_eth_src_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 208652)
+        obj.value = list(reader.read('!6B'))
+        obj.value_mask = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_inner_eth_src_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_mac(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[208652] = bsn_inner_eth_src_masked
+
+class bsn_inner_vlan_vid(oxm):
+    type_len = 208898
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_inner_vlan_vid()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 208898)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_inner_vlan_vid {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[208898] = bsn_inner_vlan_vid
+
+class bsn_inner_vlan_vid_masked(oxm):
+    type_len = 209156
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        packed.append(struct.pack("!H", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_inner_vlan_vid_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 209156)
+        obj.value = reader.read("!H")[0]
+        obj.value_mask = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_inner_vlan_vid_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[209156] = bsn_inner_vlan_vid_masked
+
+class bsn_l3_interface_class_id(oxm):
+    type_len = 198660
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_l3_interface_class_id()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 198660)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_l3_interface_class_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[198660] = bsn_l3_interface_class_id
+
+class bsn_l3_interface_class_id_masked(oxm):
+    type_len = 198920
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_l3_interface_class_id_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 198920)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_l3_interface_class_id_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[198920] = bsn_l3_interface_class_id_masked
+
+class bsn_l3_src_class_id(oxm):
+    type_len = 199172
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_l3_src_class_id()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 199172)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_l3_src_class_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[199172] = bsn_l3_src_class_id
+
+class bsn_l3_src_class_id_masked(oxm):
+    type_len = 199432
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_l3_src_class_id_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 199432)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_l3_src_class_id_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[199432] = bsn_l3_src_class_id_masked
+
+class bsn_lag_id(oxm):
+    type_len = 197124
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_lag_id()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 197124)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_lag_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[197124] = bsn_lag_id
+
+class bsn_lag_id_masked(oxm):
+    type_len = 197384
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_lag_id_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 197384)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_lag_id_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[197384] = bsn_lag_id_masked
+
+class bsn_tcp_flags(oxm):
+    type_len = 204802
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_tcp_flags()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 204802)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_tcp_flags {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[204802] = bsn_tcp_flags
+
+class bsn_tcp_flags_masked(oxm):
+    type_len = 205060
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        packed.append(struct.pack("!H", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_tcp_flags_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 205060)
+        obj.value = reader.read("!H")[0]
+        obj.value_mask = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_tcp_flags_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[205060] = bsn_tcp_flags_masked
+
+class bsn_udf0(oxm):
+    type_len = 200708
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf0()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 200708)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf0 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[200708] = bsn_udf0
+
+class bsn_udf0_masked(oxm):
+    type_len = 200968
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf0_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 200968)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf0_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[200968] = bsn_udf0_masked
+
+class bsn_udf1(oxm):
+    type_len = 201220
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf1()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 201220)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf1 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[201220] = bsn_udf1
+
+class bsn_udf1_masked(oxm):
+    type_len = 201480
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf1_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 201480)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf1_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[201480] = bsn_udf1_masked
+
+class bsn_udf2(oxm):
+    type_len = 201732
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf2()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 201732)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf2 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[201732] = bsn_udf2
+
+class bsn_udf2_masked(oxm):
+    type_len = 201992
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf2_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 201992)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf2_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[201992] = bsn_udf2_masked
+
+class bsn_udf3(oxm):
+    type_len = 202244
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf3()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 202244)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf3 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[202244] = bsn_udf3
+
+class bsn_udf3_masked(oxm):
+    type_len = 202504
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf3_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 202504)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf3_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[202504] = bsn_udf3_masked
+
+class bsn_udf4(oxm):
+    type_len = 202756
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf4()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 202756)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf4 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[202756] = bsn_udf4
+
+class bsn_udf4_masked(oxm):
+    type_len = 203016
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf4_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 203016)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf4_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[203016] = bsn_udf4_masked
+
+class bsn_udf5(oxm):
+    type_len = 203268
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf5()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 203268)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf5 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[203268] = bsn_udf5
+
+class bsn_udf5_masked(oxm):
+    type_len = 203528
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf5_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 203528)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf5_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[203528] = bsn_udf5_masked
+
+class bsn_udf6(oxm):
+    type_len = 203780
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf6()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 203780)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf6 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[203780] = bsn_udf6
+
+class bsn_udf6_masked(oxm):
+    type_len = 204040
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf6_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 204040)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf6_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[204040] = bsn_udf6_masked
+
+class bsn_udf7(oxm):
+    type_len = 204292
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf7()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 204292)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf7 {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[204292] = bsn_udf7
+
+class bsn_udf7_masked(oxm):
+    type_len = 204552
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_udf7_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 204552)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_udf7_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[204552] = bsn_udf7_masked
+
+class bsn_vlan_xlate_port_group_id(oxm):
+    type_len = 205316
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vlan_xlate_port_group_id()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 205316)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vlan_xlate_port_group_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[205316] = bsn_vlan_xlate_port_group_id
+
+class bsn_vlan_xlate_port_group_id_masked(oxm):
+    type_len = 205576
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vlan_xlate_port_group_id_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 205576)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vlan_xlate_port_group_id_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[205576] = bsn_vlan_xlate_port_group_id_masked
+
+class bsn_vrf(oxm):
+    type_len = 197636
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vrf()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 197636)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vrf {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[197636] = bsn_vrf
+
+class bsn_vrf_masked(oxm):
+    type_len = 197896
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vrf_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 197896)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vrf_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[197896] = bsn_vrf_masked
+
+class bsn_vxlan_network_id(oxm):
+    type_len = 207364
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vxlan_network_id()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 207364)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vxlan_network_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[207364] = bsn_vxlan_network_id
+
+class bsn_vxlan_network_id_masked(oxm):
+    type_len = 207624
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_vxlan_network_id_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 207624)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_vxlan_network_id_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[207624] = bsn_vxlan_network_id_masked
+
+class eth_dst(oxm):
+    type_len = 2147485190
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = eth_dst()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147485190)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("eth_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147485190] = eth_dst
+
+class eth_dst_masked(oxm):
+    type_len = 2147485452
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        packed.append(struct.pack("!6B", *self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = eth_dst_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147485452)
+        obj.value = list(reader.read('!6B'))
+        obj.value_mask = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("eth_dst_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_mac(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147485452] = eth_dst_masked
+
+class eth_src(oxm):
+    type_len = 2147485702
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = eth_src()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147485702)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("eth_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147485702] = eth_src
+
+class eth_src_masked(oxm):
+    type_len = 2147485964
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        packed.append(struct.pack("!6B", *self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = eth_src_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147485964)
+        obj.value = list(reader.read('!6B'))
+        obj.value_mask = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("eth_src_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_mac(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147485964] = eth_src_masked
+
+class eth_type(oxm):
+    type_len = 2147486210
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = eth_type()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147486210)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("eth_type {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147486210] = eth_type
+
+class eth_type_masked(oxm):
+    type_len = 2147486468
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        packed.append(struct.pack("!H", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = eth_type_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147486468)
+        obj.value = reader.read("!H")[0]
+        obj.value_mask = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("eth_type_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147486468] = eth_type_masked
+
+class icmpv4_code(oxm):
+    type_len = 2147493889
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = icmpv4_code()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147493889)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("icmpv4_code {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147493889] = icmpv4_code
+
+class icmpv4_code_masked(oxm):
+    type_len = 2147494146
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        packed.append(struct.pack("!B", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = icmpv4_code_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147494146)
+        obj.value = reader.read("!B")[0]
+        obj.value_mask = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("icmpv4_code_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147494146] = icmpv4_code_masked
+
+class icmpv4_type(oxm):
+    type_len = 2147493377
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = icmpv4_type()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147493377)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("icmpv4_type {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147493377] = icmpv4_type
+
+class icmpv4_type_masked(oxm):
+    type_len = 2147493634
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        packed.append(struct.pack("!B", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = icmpv4_type_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147493634)
+        obj.value = reader.read("!B")[0]
+        obj.value_mask = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("icmpv4_type_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147493634] = icmpv4_type_masked
+
+class icmpv6_code(oxm):
+    type_len = 2147499009
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = icmpv6_code()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147499009)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("icmpv6_code {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147499009] = icmpv6_code
+
+class icmpv6_code_masked(oxm):
+    type_len = 2147499266
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        packed.append(struct.pack("!B", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = icmpv6_code_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147499266)
+        obj.value = reader.read("!B")[0]
+        obj.value_mask = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("icmpv6_code_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147499266] = icmpv6_code_masked
+
+class icmpv6_type(oxm):
+    type_len = 2147498497
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = icmpv6_type()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147498497)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("icmpv6_type {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147498497] = icmpv6_type
+
+class icmpv6_type_masked(oxm):
+    type_len = 2147498754
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        packed.append(struct.pack("!B", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = icmpv6_type_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147498754)
+        obj.value = reader.read("!B")[0]
+        obj.value_mask = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("icmpv6_type_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147498754] = icmpv6_type_masked
+
+class in_phy_port(oxm):
+    type_len = 2147484164
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(util.pack_port_no(self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = in_phy_port()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147484164)
+        obj.value = util.unpack_port_no(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("in_phy_port {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_port(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147484164] = in_phy_port
+
+class in_phy_port_masked(oxm):
+    type_len = 2147484424
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(util.pack_port_no(self.value))
+        packed.append(util.pack_port_no(self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = in_phy_port_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147484424)
+        obj.value = util.unpack_port_no(reader)
+        obj.value_mask = util.unpack_port_no(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("in_phy_port_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_port(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_port(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147484424] = in_phy_port_masked
+
+class in_port(oxm):
+    type_len = 2147483652
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(util.pack_port_no(self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = in_port()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147483652)
+        obj.value = util.unpack_port_no(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("in_port {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_port(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147483652] = in_port
+
+class in_port_masked(oxm):
+    type_len = 2147483912
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(util.pack_port_no(self.value))
+        packed.append(util.pack_port_no(self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = in_port_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147483912)
+        obj.value = util.unpack_port_no(reader)
+        obj.value_mask = util.unpack_port_no(reader)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("in_port_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_port(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_port(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147483912] = in_port_masked
+
+class ip_dscp(oxm):
+    type_len = 2147487745
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ip_dscp()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147487745)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ip_dscp {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147487745] = ip_dscp
+
+class ip_dscp_masked(oxm):
+    type_len = 2147488002
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        packed.append(struct.pack("!B", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ip_dscp_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147488002)
+        obj.value = reader.read("!B")[0]
+        obj.value_mask = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ip_dscp_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147488002] = ip_dscp_masked
+
+class ip_ecn(oxm):
+    type_len = 2147488257
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ip_ecn()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147488257)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ip_ecn {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147488257] = ip_ecn
+
+class ip_ecn_masked(oxm):
+    type_len = 2147488514
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        packed.append(struct.pack("!B", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ip_ecn_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147488514)
+        obj.value = reader.read("!B")[0]
+        obj.value_mask = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ip_ecn_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147488514] = ip_ecn_masked
+
+class ip_proto(oxm):
+    type_len = 2147488769
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ip_proto()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147488769)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ip_proto {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147488769] = ip_proto
+
+class ip_proto_masked(oxm):
+    type_len = 2147489026
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        packed.append(struct.pack("!B", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ip_proto_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147489026)
+        obj.value = reader.read("!B")[0]
+        obj.value_mask = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ip_proto_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147489026] = ip_proto_masked
+
+class ipv4_dst(oxm):
+    type_len = 2147489796
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv4_dst()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147489796)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv4_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147489796] = ipv4_dst
+
+class ipv4_dst_masked(oxm):
+    type_len = 2147490056
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv4_dst_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147490056)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv4_dst_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_ipv4(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147490056] = ipv4_dst_masked
+
+class ipv4_src(oxm):
+    type_len = 2147489284
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv4_src()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147489284)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv4_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147489284] = ipv4_src
+
+class ipv4_src_masked(oxm):
+    type_len = 2147489544
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv4_src_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147489544)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv4_src_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_ipv4(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147489544] = ipv4_src_masked
+
+class ipv6_dst(oxm):
+    type_len = 2147497488
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!16s", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_dst()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147497488)
+        obj.value = reader.read('!16s')[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147497488] = ipv6_dst
+
+class ipv6_dst_masked(oxm):
+    type_len = 2147497760
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!16s", self.value))
+        packed.append(struct.pack("!16s", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_dst_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147497760)
+        obj.value = reader.read('!16s')[0]
+        obj.value_mask = reader.read('!16s')[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_dst_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.pp(self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147497760] = ipv6_dst_masked
+
+class ipv6_exthdr(oxm):
+    type_len = 2147503618
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_exthdr()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147503618)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_exthdr {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147503618] = ipv6_exthdr
+
+class ipv6_exthdr_masked(oxm):
+    type_len = 2147503876
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        packed.append(struct.pack("!H", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_exthdr_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147503876)
+        obj.value = reader.read("!H")[0]
+        obj.value_mask = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_exthdr_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147503876] = ipv6_exthdr_masked
+
+class ipv6_flabel(oxm):
+    type_len = 2147497988
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_flabel()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147497988)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_flabel {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147497988] = ipv6_flabel
+
+class ipv6_flabel_masked(oxm):
+    type_len = 2147498248
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_flabel_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147498248)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_flabel_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147498248] = ipv6_flabel_masked
+
+class ipv6_nd_sll(oxm):
+    type_len = 2147500038
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_nd_sll()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147500038)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_nd_sll {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147500038] = ipv6_nd_sll
+
+class ipv6_nd_sll_masked(oxm):
+    type_len = 2147500300
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        packed.append(struct.pack("!6B", *self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_nd_sll_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147500300)
+        obj.value = list(reader.read('!6B'))
+        obj.value_mask = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_nd_sll_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_mac(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147500300] = ipv6_nd_sll_masked
+
+class ipv6_nd_target(oxm):
+    type_len = 2147499536
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!16s", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_nd_target()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147499536)
+        obj.value = reader.read('!16s')[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_nd_target {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147499536] = ipv6_nd_target
+
+class ipv6_nd_target_masked(oxm):
+    type_len = 2147499808
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!16s", self.value))
+        packed.append(struct.pack("!16s", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_nd_target_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147499808)
+        obj.value = reader.read('!16s')[0]
+        obj.value_mask = reader.read('!16s')[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_nd_target_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.pp(self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147499808] = ipv6_nd_target_masked
+
+class ipv6_nd_tll(oxm):
+    type_len = 2147500550
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_nd_tll()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147500550)
+        obj.value = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_nd_tll {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147500550] = ipv6_nd_tll
+
+class ipv6_nd_tll_masked(oxm):
+    type_len = 2147500812
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = [0,0,0,0,0,0]
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = [0,0,0,0,0,0]
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!6B", *self.value))
+        packed.append(struct.pack("!6B", *self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_nd_tll_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147500812)
+        obj.value = list(reader.read('!6B'))
+        obj.value_mask = list(reader.read('!6B'))
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_nd_tll_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_mac(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_mac(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147500812] = ipv6_nd_tll_masked
+
+class ipv6_src(oxm):
+    type_len = 2147496976
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!16s", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_src()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147496976)
+        obj.value = reader.read('!16s')[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147496976] = ipv6_src
+
+class ipv6_src_masked(oxm):
+    type_len = 2147497248
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!16s", self.value))
+        packed.append(struct.pack("!16s", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ipv6_src_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147497248)
+        obj.value = reader.read('!16s')[0]
+        obj.value_mask = reader.read('!16s')[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ipv6_src_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.pp(self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.pp(self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147497248] = ipv6_src_masked
+
+class metadata(oxm):
+    type_len = 2147484680
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!Q", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = metadata()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147484680)
+        obj.value = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("metadata {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147484680] = metadata
+
+class metadata_masked(oxm):
+    type_len = 2147484944
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!Q", self.value))
+        packed.append(struct.pack("!Q", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = metadata_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147484944)
+        obj.value = reader.read("!Q")[0]
+        obj.value_mask = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("metadata_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147484944] = metadata_masked
+
+class mpls_bos(oxm):
+    type_len = 2147502081
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = mpls_bos()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147502081)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("mpls_bos {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147502081] = mpls_bos
+
+class mpls_bos_masked(oxm):
+    type_len = 2147502338
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        packed.append(struct.pack("!B", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = mpls_bos_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147502338)
+        obj.value = reader.read("!B")[0]
+        obj.value_mask = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("mpls_bos_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147502338] = mpls_bos_masked
+
+class mpls_label(oxm):
+    type_len = 2147501060
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = mpls_label()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147501060)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("mpls_label {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147501060] = mpls_label
+
+class mpls_label_masked(oxm):
+    type_len = 2147501320
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = mpls_label_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147501320)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("mpls_label_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147501320] = mpls_label_masked
+
+class mpls_tc(oxm):
+    type_len = 2147501569
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = mpls_tc()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147501569)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("mpls_tc {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147501569] = mpls_tc
+
+class mpls_tc_masked(oxm):
+    type_len = 2147501826
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        packed.append(struct.pack("!B", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = mpls_tc_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147501826)
+        obj.value = reader.read("!B")[0]
+        obj.value_mask = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("mpls_tc_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147501826] = mpls_tc_masked
+
+class pbb_uca(oxm):
+    type_len = 2147504641
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = pbb_uca()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147504641)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("pbb_uca {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147504641] = pbb_uca
+
+class pbb_uca_masked(oxm):
+    type_len = 2147504898
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        packed.append(struct.pack("!B", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = pbb_uca_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147504898)
+        obj.value = reader.read("!B")[0]
+        obj.value_mask = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("pbb_uca_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147504898] = pbb_uca_masked
+
+class sctp_dst(oxm):
+    type_len = 2147492866
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = sctp_dst()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147492866)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("sctp_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147492866] = sctp_dst
+
+class sctp_dst_masked(oxm):
+    type_len = 2147493124
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        packed.append(struct.pack("!H", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = sctp_dst_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147493124)
+        obj.value = reader.read("!H")[0]
+        obj.value_mask = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("sctp_dst_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147493124] = sctp_dst_masked
+
+class sctp_src(oxm):
+    type_len = 2147492354
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = sctp_src()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147492354)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("sctp_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147492354] = sctp_src
+
+class sctp_src_masked(oxm):
+    type_len = 2147492612
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        packed.append(struct.pack("!H", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = sctp_src_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147492612)
+        obj.value = reader.read("!H")[0]
+        obj.value_mask = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("sctp_src_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147492612] = sctp_src_masked
+
+class tcp_dst(oxm):
+    type_len = 2147490818
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = tcp_dst()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147490818)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("tcp_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147490818] = tcp_dst
+
+class tcp_dst_masked(oxm):
+    type_len = 2147491076
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        packed.append(struct.pack("!H", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = tcp_dst_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147491076)
+        obj.value = reader.read("!H")[0]
+        obj.value_mask = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("tcp_dst_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147491076] = tcp_dst_masked
+
+class tcp_src(oxm):
+    type_len = 2147490306
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = tcp_src()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147490306)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("tcp_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147490306] = tcp_src
+
+class tcp_src_masked(oxm):
+    type_len = 2147490564
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        packed.append(struct.pack("!H", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = tcp_src_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147490564)
+        obj.value = reader.read("!H")[0]
+        obj.value_mask = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("tcp_src_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147490564] = tcp_src_masked
+
+class tunnel_id(oxm):
+    type_len = 2147503112
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!Q", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = tunnel_id()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147503112)
+        obj.value = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("tunnel_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147503112] = tunnel_id
+
+class tunnel_id_masked(oxm):
+    type_len = 2147503376
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!Q", self.value))
+        packed.append(struct.pack("!Q", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = tunnel_id_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147503376)
+        obj.value = reader.read("!Q")[0]
+        obj.value_mask = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("tunnel_id_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147503376] = tunnel_id_masked
+
+class tunnel_ipv4_dst(oxm):
+    type_len = 81924
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = tunnel_ipv4_dst()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 81924)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("tunnel_ipv4_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[81924] = tunnel_ipv4_dst
+
+class tunnel_ipv4_dst_masked(oxm):
+    type_len = 82184
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = tunnel_ipv4_dst_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 82184)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("tunnel_ipv4_dst_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_ipv4(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[82184] = tunnel_ipv4_dst_masked
+
+class tunnel_ipv4_src(oxm):
+    type_len = 81412
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = tunnel_ipv4_src()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 81412)
+        obj.value = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("tunnel_ipv4_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[81412] = tunnel_ipv4_src
+
+class tunnel_ipv4_src_masked(oxm):
+    type_len = 81672
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!L", self.value))
+        packed.append(struct.pack("!L", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = tunnel_ipv4_src_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 81672)
+        obj.value = reader.read("!L")[0]
+        obj.value_mask = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("tunnel_ipv4_src_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text(util.pretty_ipv4(self.value))
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text(util.pretty_ipv4(self.value_mask))
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[81672] = tunnel_ipv4_src_masked
+
+class udp_dst(oxm):
+    type_len = 2147491842
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = udp_dst()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147491842)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("udp_dst {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147491842] = udp_dst
+
+class udp_dst_masked(oxm):
+    type_len = 2147492100
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        packed.append(struct.pack("!H", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = udp_dst_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147492100)
+        obj.value = reader.read("!H")[0]
+        obj.value_mask = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("udp_dst_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147492100] = udp_dst_masked
+
+class udp_src(oxm):
+    type_len = 2147491330
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = udp_src()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147491330)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("udp_src {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147491330] = udp_src
+
+class udp_src_masked(oxm):
+    type_len = 2147491588
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        packed.append(struct.pack("!H", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = udp_src_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147491588)
+        obj.value = reader.read("!H")[0]
+        obj.value_mask = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("udp_src_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147491588] = udp_src_masked
+
+class vlan_pcp(oxm):
+    type_len = 2147487233
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = vlan_pcp()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147487233)
+        obj.value = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("vlan_pcp {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147487233] = vlan_pcp
+
+class vlan_pcp_masked(oxm):
+    type_len = 2147487490
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!B", self.value))
+        packed.append(struct.pack("!B", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = vlan_pcp_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147487490)
+        obj.value = reader.read("!B")[0]
+        obj.value_mask = reader.read("!B")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("vlan_pcp_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147487490] = vlan_pcp_masked
+
+class vlan_vid(oxm):
+    type_len = 2147486722
+
+    def __init__(self, value=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = vlan_vid()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147486722)
+        obj.value = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("vlan_vid {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147486722] = vlan_vid
+
+class vlan_vid_masked(oxm):
+    type_len = 2147486980
+
+    def __init__(self, value=None, value_mask=None):
+        if value != None:
+            self.value = value
+        else:
+            self.value = 0
+        if value_mask != None:
+            self.value_mask = value_mask
+        else:
+            self.value_mask = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!L", self.type_len))
+        packed.append(struct.pack("!H", self.value))
+        packed.append(struct.pack("!H", self.value_mask))
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = vlan_vid_masked()
+        _type_len = reader.read("!L")[0]
+        assert(_type_len == 2147486980)
+        obj.value = reader.read("!H")[0]
+        obj.value_mask = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.value != other.value: return False
+        if self.value_mask != other.value_mask: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("vlan_vid_masked {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("value = ");
+                q.text("%#x" % self.value)
+                q.text(","); q.breakable()
+                q.text("value_mask = ");
+                q.text("%#x" % self.value_mask)
+            q.breakable()
+        q.text('}')
+
+oxm.subtypes[2147486980] = vlan_vid_masked
+
+
diff --git a/Fabric/Utilities/src/python/loxi/of14/port_desc_prop.py b/Fabric/Utilities/src/python/loxi/of14/port_desc_prop.py
new file mode 100644
index 0000000..71f281d
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of14/port_desc_prop.py
@@ -0,0 +1,517 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of14']
+
+class port_desc_prop(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = port_desc_prop.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = port_desc_prop()
+        obj.type = reader.read("!H")[0]
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_desc_prop {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class experimenter(port_desc_prop):
+    subtypes = {}
+
+    type = 65535
+
+    def __init__(self, experimenter=None):
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 4)
+        subclass = experimenter.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = experimenter()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.experimenter = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.experimenter != other.experimenter: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+port_desc_prop.subtypes[65535] = experimenter
+
+class bsn(experimenter):
+    subtypes = {}
+
+    type = 65535
+    experimenter = 6035143
+
+    def __init__(self, exp_type=None):
+        if exp_type != None:
+            self.exp_type = exp_type
+        else:
+            self.exp_type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.exp_type))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 8)
+        subclass = bsn.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = bsn()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        obj.exp_type = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.exp_type != other.exp_type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+experimenter.subtypes[6035143] = bsn
+
+class bsn_generation_id(bsn):
+    type = 65535
+    experimenter = 6035143
+    exp_type = 1
+
+    def __init__(self, generation_id=None):
+        if generation_id != None:
+            self.generation_id = generation_id
+        else:
+            self.generation_id = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.exp_type))
+        packed.append(struct.pack("!Q", self.generation_id))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_generation_id()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _exp_type = reader.read("!L")[0]
+        assert(_exp_type == 1)
+        obj.generation_id = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.generation_id != other.generation_id: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_generation_id {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("generation_id = ");
+                q.text("%#x" % self.generation_id)
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[1] = bsn_generation_id
+
+class bsn_uplink(bsn):
+    type = 65535
+    experimenter = 6035143
+    exp_type = 0
+
+    def __init__(self):
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.exp_type))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = bsn_uplink()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        _experimenter = reader.read("!L")[0]
+        assert(_experimenter == 6035143)
+        _exp_type = reader.read("!L")[0]
+        assert(_exp_type == 0)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("bsn_uplink {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+bsn.subtypes[0] = bsn_uplink
+
+class ethernet(port_desc_prop):
+    type = 0
+
+    def __init__(self, curr=None, advertised=None, supported=None, peer=None, curr_speed=None, max_speed=None):
+        if curr != None:
+            self.curr = curr
+        else:
+            self.curr = 0
+        if advertised != None:
+            self.advertised = advertised
+        else:
+            self.advertised = 0
+        if supported != None:
+            self.supported = supported
+        else:
+            self.supported = 0
+        if peer != None:
+            self.peer = peer
+        else:
+            self.peer = 0
+        if curr_speed != None:
+            self.curr_speed = curr_speed
+        else:
+            self.curr_speed = 0
+        if max_speed != None:
+            self.max_speed = max_speed
+        else:
+            self.max_speed = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.curr))
+        packed.append(struct.pack("!L", self.advertised))
+        packed.append(struct.pack("!L", self.supported))
+        packed.append(struct.pack("!L", self.peer))
+        packed.append(struct.pack("!L", self.curr_speed))
+        packed.append(struct.pack("!L", self.max_speed))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ethernet()
+        _type = reader.read("!H")[0]
+        assert(_type == 0)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        reader.skip(4)
+        obj.curr = reader.read("!L")[0]
+        obj.advertised = reader.read("!L")[0]
+        obj.supported = reader.read("!L")[0]
+        obj.peer = reader.read("!L")[0]
+        obj.curr_speed = reader.read("!L")[0]
+        obj.max_speed = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.curr != other.curr: return False
+        if self.advertised != other.advertised: return False
+        if self.supported != other.supported: return False
+        if self.peer != other.peer: return False
+        if self.curr_speed != other.curr_speed: return False
+        if self.max_speed != other.max_speed: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ethernet {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("curr = ");
+                q.text("%#x" % self.curr)
+                q.text(","); q.breakable()
+                q.text("advertised = ");
+                q.text("%#x" % self.advertised)
+                q.text(","); q.breakable()
+                q.text("supported = ");
+                q.text("%#x" % self.supported)
+                q.text(","); q.breakable()
+                q.text("peer = ");
+                q.text("%#x" % self.peer)
+                q.text(","); q.breakable()
+                q.text("curr_speed = ");
+                q.text("%#x" % self.curr_speed)
+                q.text(","); q.breakable()
+                q.text("max_speed = ");
+                q.text("%#x" % self.max_speed)
+            q.breakable()
+        q.text('}')
+
+port_desc_prop.subtypes[0] = ethernet
+
+class optical(port_desc_prop):
+    type = 1
+
+    def __init__(self, supported=None, tx_min_freq_lmda=None, tx_max_freq_lmda=None, tx_grid_freq_lmda=None, rx_min_freq_lmda=None, rx_max_freq_lmda=None, rx_grid_freq_lmda=None, tx_pwr_min=None, tx_pwr_max=None):
+        if supported != None:
+            self.supported = supported
+        else:
+            self.supported = 0
+        if tx_min_freq_lmda != None:
+            self.tx_min_freq_lmda = tx_min_freq_lmda
+        else:
+            self.tx_min_freq_lmda = 0
+        if tx_max_freq_lmda != None:
+            self.tx_max_freq_lmda = tx_max_freq_lmda
+        else:
+            self.tx_max_freq_lmda = 0
+        if tx_grid_freq_lmda != None:
+            self.tx_grid_freq_lmda = tx_grid_freq_lmda
+        else:
+            self.tx_grid_freq_lmda = 0
+        if rx_min_freq_lmda != None:
+            self.rx_min_freq_lmda = rx_min_freq_lmda
+        else:
+            self.rx_min_freq_lmda = 0
+        if rx_max_freq_lmda != None:
+            self.rx_max_freq_lmda = rx_max_freq_lmda
+        else:
+            self.rx_max_freq_lmda = 0
+        if rx_grid_freq_lmda != None:
+            self.rx_grid_freq_lmda = rx_grid_freq_lmda
+        else:
+            self.rx_grid_freq_lmda = 0
+        if tx_pwr_min != None:
+            self.tx_pwr_min = tx_pwr_min
+        else:
+            self.tx_pwr_min = 0
+        if tx_pwr_max != None:
+            self.tx_pwr_max = tx_pwr_max
+        else:
+            self.tx_pwr_max = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.supported))
+        packed.append(struct.pack("!L", self.tx_min_freq_lmda))
+        packed.append(struct.pack("!L", self.tx_max_freq_lmda))
+        packed.append(struct.pack("!L", self.tx_grid_freq_lmda))
+        packed.append(struct.pack("!L", self.rx_min_freq_lmda))
+        packed.append(struct.pack("!L", self.rx_max_freq_lmda))
+        packed.append(struct.pack("!L", self.rx_grid_freq_lmda))
+        packed.append(struct.pack("!L", self.tx_pwr_min))
+        packed.append(struct.pack("!L", self.tx_pwr_max))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = optical()
+        _type = reader.read("!H")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        reader.skip(4)
+        obj.supported = reader.read("!L")[0]
+        obj.tx_min_freq_lmda = reader.read("!L")[0]
+        obj.tx_max_freq_lmda = reader.read("!L")[0]
+        obj.tx_grid_freq_lmda = reader.read("!L")[0]
+        obj.rx_min_freq_lmda = reader.read("!L")[0]
+        obj.rx_max_freq_lmda = reader.read("!L")[0]
+        obj.rx_grid_freq_lmda = reader.read("!L")[0]
+        obj.tx_pwr_min = reader.read("!L")[0]
+        obj.tx_pwr_max = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.supported != other.supported: return False
+        if self.tx_min_freq_lmda != other.tx_min_freq_lmda: return False
+        if self.tx_max_freq_lmda != other.tx_max_freq_lmda: return False
+        if self.tx_grid_freq_lmda != other.tx_grid_freq_lmda: return False
+        if self.rx_min_freq_lmda != other.rx_min_freq_lmda: return False
+        if self.rx_max_freq_lmda != other.rx_max_freq_lmda: return False
+        if self.rx_grid_freq_lmda != other.rx_grid_freq_lmda: return False
+        if self.tx_pwr_min != other.tx_pwr_min: return False
+        if self.tx_pwr_max != other.tx_pwr_max: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("optical {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("supported = ");
+                q.text("%#x" % self.supported)
+                q.text(","); q.breakable()
+                q.text("tx_min_freq_lmda = ");
+                q.text("%#x" % self.tx_min_freq_lmda)
+                q.text(","); q.breakable()
+                q.text("tx_max_freq_lmda = ");
+                q.text("%#x" % self.tx_max_freq_lmda)
+                q.text(","); q.breakable()
+                q.text("tx_grid_freq_lmda = ");
+                q.text("%#x" % self.tx_grid_freq_lmda)
+                q.text(","); q.breakable()
+                q.text("rx_min_freq_lmda = ");
+                q.text("%#x" % self.rx_min_freq_lmda)
+                q.text(","); q.breakable()
+                q.text("rx_max_freq_lmda = ");
+                q.text("%#x" % self.rx_max_freq_lmda)
+                q.text(","); q.breakable()
+                q.text("rx_grid_freq_lmda = ");
+                q.text("%#x" % self.rx_grid_freq_lmda)
+                q.text(","); q.breakable()
+                q.text("tx_pwr_min = ");
+                q.text("%#x" % self.tx_pwr_min)
+                q.text(","); q.breakable()
+                q.text("tx_pwr_max = ");
+                q.text("%#x" % self.tx_pwr_max)
+            q.breakable()
+        q.text('}')
+
+port_desc_prop.subtypes[1] = optical
+
+
diff --git a/Fabric/Utilities/src/python/loxi/of14/port_mod_prop.py b/Fabric/Utilities/src/python/loxi/of14/port_mod_prop.py
new file mode 100644
index 0000000..ce9e448
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of14/port_mod_prop.py
@@ -0,0 +1,275 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of14']
+
+class port_mod_prop(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = port_mod_prop.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = port_mod_prop()
+        obj.type = reader.read("!H")[0]
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_mod_prop {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class ethernet(port_mod_prop):
+    type = 0
+
+    def __init__(self, advertise=None):
+        if advertise != None:
+            self.advertise = advertise
+        else:
+            self.advertise = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.advertise))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ethernet()
+        _type = reader.read("!H")[0]
+        assert(_type == 0)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.advertise = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.advertise != other.advertise: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ethernet {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("advertise = ");
+                q.text("%#x" % self.advertise)
+            q.breakable()
+        q.text('}')
+
+port_mod_prop.subtypes[0] = ethernet
+
+class experimenter(port_mod_prop):
+    subtypes = {}
+
+    type = 65535
+
+    def __init__(self, experimenter=None, exp_type=None):
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if exp_type != None:
+            self.exp_type = exp_type
+        else:
+            self.exp_type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.exp_type))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 4)
+        subclass = experimenter.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = experimenter()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.experimenter = reader.read("!L")[0]
+        obj.exp_type = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.experimenter != other.experimenter: return False
+        if self.exp_type != other.exp_type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("exp_type = ");
+                q.text("%#x" % self.exp_type)
+            q.breakable()
+        q.text('}')
+
+port_mod_prop.subtypes[65535] = experimenter
+
+class optical(port_mod_prop):
+    type = 1
+
+    def __init__(self, configure=None, freq_ldma=None, fl_offset=None, grid_span=None, tx_pwr=None):
+        if configure != None:
+            self.configure = configure
+        else:
+            self.configure = 0
+        if freq_ldma != None:
+            self.freq_ldma = freq_ldma
+        else:
+            self.freq_ldma = 0
+        if fl_offset != None:
+            self.fl_offset = fl_offset
+        else:
+            self.fl_offset = 0
+        if grid_span != None:
+            self.grid_span = grid_span
+        else:
+            self.grid_span = 0
+        if tx_pwr != None:
+            self.tx_pwr = tx_pwr
+        else:
+            self.tx_pwr = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.configure))
+        packed.append(struct.pack("!L", self.freq_ldma))
+        packed.append(struct.pack("!L", self.fl_offset))
+        packed.append(struct.pack("!L", self.grid_span))
+        packed.append(struct.pack("!L", self.tx_pwr))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = optical()
+        _type = reader.read("!H")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.configure = reader.read("!L")[0]
+        obj.freq_ldma = reader.read("!L")[0]
+        obj.fl_offset = reader.read("!L")[0]
+        obj.grid_span = reader.read("!L")[0]
+        obj.tx_pwr = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.configure != other.configure: return False
+        if self.freq_ldma != other.freq_ldma: return False
+        if self.fl_offset != other.fl_offset: return False
+        if self.grid_span != other.grid_span: return False
+        if self.tx_pwr != other.tx_pwr: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("optical {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("configure = ");
+                q.text("%#x" % self.configure)
+                q.text(","); q.breakable()
+                q.text("freq_ldma = ");
+                q.text("%#x" % self.freq_ldma)
+                q.text(","); q.breakable()
+                q.text("fl_offset = ");
+                q.text("%#x" % self.fl_offset)
+                q.text(","); q.breakable()
+                q.text("grid_span = ");
+                q.text("%#x" % self.grid_span)
+                q.text(","); q.breakable()
+                q.text("tx_pwr = ");
+                q.text("%#x" % self.tx_pwr)
+            q.breakable()
+        q.text('}')
+
+port_mod_prop.subtypes[1] = optical
+
+
diff --git a/Fabric/Utilities/src/python/loxi/of14/port_stats_prop.py b/Fabric/Utilities/src/python/loxi/of14/port_stats_prop.py
new file mode 100644
index 0000000..752ac6d
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of14/port_stats_prop.py
@@ -0,0 +1,379 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of14']
+
+class port_stats_prop(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = port_stats_prop.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = port_stats_prop()
+        obj.type = reader.read("!H")[0]
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("port_stats_prop {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class ethernet(port_stats_prop):
+    type = 0
+
+    def __init__(self, rx_frame_err=None, rx_over_err=None, rx_crc_err=None, collisions=None):
+        if rx_frame_err != None:
+            self.rx_frame_err = rx_frame_err
+        else:
+            self.rx_frame_err = 0
+        if rx_over_err != None:
+            self.rx_over_err = rx_over_err
+        else:
+            self.rx_over_err = 0
+        if rx_crc_err != None:
+            self.rx_crc_err = rx_crc_err
+        else:
+            self.rx_crc_err = 0
+        if collisions != None:
+            self.collisions = collisions
+        else:
+            self.collisions = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!Q", self.rx_frame_err))
+        packed.append(struct.pack("!Q", self.rx_over_err))
+        packed.append(struct.pack("!Q", self.rx_crc_err))
+        packed.append(struct.pack("!Q", self.collisions))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = ethernet()
+        _type = reader.read("!H")[0]
+        assert(_type == 0)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        reader.skip(4)
+        obj.rx_frame_err = reader.read("!Q")[0]
+        obj.rx_over_err = reader.read("!Q")[0]
+        obj.rx_crc_err = reader.read("!Q")[0]
+        obj.collisions = reader.read("!Q")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.rx_frame_err != other.rx_frame_err: return False
+        if self.rx_over_err != other.rx_over_err: return False
+        if self.rx_crc_err != other.rx_crc_err: return False
+        if self.collisions != other.collisions: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("ethernet {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("rx_frame_err = ");
+                q.text("%#x" % self.rx_frame_err)
+                q.text(","); q.breakable()
+                q.text("rx_over_err = ");
+                q.text("%#x" % self.rx_over_err)
+                q.text(","); q.breakable()
+                q.text("rx_crc_err = ");
+                q.text("%#x" % self.rx_crc_err)
+                q.text(","); q.breakable()
+                q.text("collisions = ");
+                q.text("%#x" % self.collisions)
+            q.breakable()
+        q.text('}')
+
+port_stats_prop.subtypes[0] = ethernet
+
+class experimenter(port_stats_prop):
+    subtypes = {}
+
+    type = 65535
+
+    def __init__(self, experimenter=None, exp_type=None, experimenter_data=None):
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if exp_type != None:
+            self.exp_type = exp_type
+        else:
+            self.exp_type = 0
+        if experimenter_data != None:
+            self.experimenter_data = experimenter_data
+        else:
+            self.experimenter_data = ''
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.exp_type))
+        packed.append(self.experimenter_data)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 4)
+        subclass = experimenter.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = experimenter()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.experimenter = reader.read("!L")[0]
+        obj.exp_type = reader.read("!L")[0]
+        obj.experimenter_data = str(reader.read_all())
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.experimenter != other.experimenter: return False
+        if self.exp_type != other.exp_type: return False
+        if self.experimenter_data != other.experimenter_data: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("exp_type = ");
+                q.text("%#x" % self.exp_type)
+                q.text(","); q.breakable()
+                q.text("experimenter_data = ");
+                q.pp(self.experimenter_data)
+            q.breakable()
+        q.text('}')
+
+port_stats_prop.subtypes[65535] = experimenter
+
+class optical(port_stats_prop):
+    type = 1
+
+    def __init__(self, flags=None, tx_freq_lmda=None, tx_offset=None, tx_grid_span=None, rx_freq_lmda=None, rx_offset=None, rx_grid_span=None, tx_pwr=None, rx_pwr=None, bias_current=None, temperature=None):
+        if flags != None:
+            self.flags = flags
+        else:
+            self.flags = 0
+        if tx_freq_lmda != None:
+            self.tx_freq_lmda = tx_freq_lmda
+        else:
+            self.tx_freq_lmda = 0
+        if tx_offset != None:
+            self.tx_offset = tx_offset
+        else:
+            self.tx_offset = 0
+        if tx_grid_span != None:
+            self.tx_grid_span = tx_grid_span
+        else:
+            self.tx_grid_span = 0
+        if rx_freq_lmda != None:
+            self.rx_freq_lmda = rx_freq_lmda
+        else:
+            self.rx_freq_lmda = 0
+        if rx_offset != None:
+            self.rx_offset = rx_offset
+        else:
+            self.rx_offset = 0
+        if rx_grid_span != None:
+            self.rx_grid_span = rx_grid_span
+        else:
+            self.rx_grid_span = 0
+        if tx_pwr != None:
+            self.tx_pwr = tx_pwr
+        else:
+            self.tx_pwr = 0
+        if rx_pwr != None:
+            self.rx_pwr = rx_pwr
+        else:
+            self.rx_pwr = 0
+        if bias_current != None:
+            self.bias_current = bias_current
+        else:
+            self.bias_current = 0
+        if temperature != None:
+            self.temperature = temperature
+        else:
+            self.temperature = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append('\x00' * 4)
+        packed.append(struct.pack("!L", self.flags))
+        packed.append(struct.pack("!L", self.tx_freq_lmda))
+        packed.append(struct.pack("!L", self.tx_offset))
+        packed.append(struct.pack("!L", self.tx_grid_span))
+        packed.append(struct.pack("!L", self.rx_freq_lmda))
+        packed.append(struct.pack("!L", self.rx_offset))
+        packed.append(struct.pack("!L", self.rx_grid_span))
+        packed.append(struct.pack("!H", self.tx_pwr))
+        packed.append(struct.pack("!H", self.rx_pwr))
+        packed.append(struct.pack("!H", self.bias_current))
+        packed.append(struct.pack("!H", self.temperature))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = optical()
+        _type = reader.read("!H")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        reader.skip(4)
+        obj.flags = reader.read("!L")[0]
+        obj.tx_freq_lmda = reader.read("!L")[0]
+        obj.tx_offset = reader.read("!L")[0]
+        obj.tx_grid_span = reader.read("!L")[0]
+        obj.rx_freq_lmda = reader.read("!L")[0]
+        obj.rx_offset = reader.read("!L")[0]
+        obj.rx_grid_span = reader.read("!L")[0]
+        obj.tx_pwr = reader.read("!H")[0]
+        obj.rx_pwr = reader.read("!H")[0]
+        obj.bias_current = reader.read("!H")[0]
+        obj.temperature = reader.read("!H")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.flags != other.flags: return False
+        if self.tx_freq_lmda != other.tx_freq_lmda: return False
+        if self.tx_offset != other.tx_offset: return False
+        if self.tx_grid_span != other.tx_grid_span: return False
+        if self.rx_freq_lmda != other.rx_freq_lmda: return False
+        if self.rx_offset != other.rx_offset: return False
+        if self.rx_grid_span != other.rx_grid_span: return False
+        if self.tx_pwr != other.tx_pwr: return False
+        if self.rx_pwr != other.rx_pwr: return False
+        if self.bias_current != other.bias_current: return False
+        if self.temperature != other.temperature: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("optical {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("flags = ");
+                q.text("%#x" % self.flags)
+                q.text(","); q.breakable()
+                q.text("tx_freq_lmda = ");
+                q.text("%#x" % self.tx_freq_lmda)
+                q.text(","); q.breakable()
+                q.text("tx_offset = ");
+                q.text("%#x" % self.tx_offset)
+                q.text(","); q.breakable()
+                q.text("tx_grid_span = ");
+                q.text("%#x" % self.tx_grid_span)
+                q.text(","); q.breakable()
+                q.text("rx_freq_lmda = ");
+                q.text("%#x" % self.rx_freq_lmda)
+                q.text(","); q.breakable()
+                q.text("rx_offset = ");
+                q.text("%#x" % self.rx_offset)
+                q.text(","); q.breakable()
+                q.text("rx_grid_span = ");
+                q.text("%#x" % self.rx_grid_span)
+                q.text(","); q.breakable()
+                q.text("tx_pwr = ");
+                q.text("%#x" % self.tx_pwr)
+                q.text(","); q.breakable()
+                q.text("rx_pwr = ");
+                q.text("%#x" % self.rx_pwr)
+                q.text(","); q.breakable()
+                q.text("bias_current = ");
+                q.text("%#x" % self.bias_current)
+                q.text(","); q.breakable()
+                q.text("temperature = ");
+                q.text("%#x" % self.temperature)
+            q.breakable()
+        q.text('}')
+
+port_stats_prop.subtypes[1] = optical
+
+
diff --git a/Fabric/Utilities/src/python/loxi/of14/queue_desc_prop.py b/Fabric/Utilities/src/python/loxi/of14/queue_desc_prop.py
new file mode 100644
index 0000000..a9a70b5
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of14/queue_desc_prop.py
@@ -0,0 +1,239 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of14']
+
+class queue_desc_prop(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = queue_desc_prop.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = queue_desc_prop()
+        obj.type = reader.read("!H")[0]
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_desc_prop {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class experimenter(queue_desc_prop):
+    subtypes = {}
+
+    type = 65535
+
+    def __init__(self, experimenter=None, exp_type=None):
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if exp_type != None:
+            self.exp_type = exp_type
+        else:
+            self.exp_type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.exp_type))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 4)
+        subclass = experimenter.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = experimenter()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.experimenter = reader.read("!L")[0]
+        obj.exp_type = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.experimenter != other.experimenter: return False
+        if self.exp_type != other.exp_type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("exp_type = ");
+                q.text("%#x" % self.exp_type)
+            q.breakable()
+        q.text('}')
+
+queue_desc_prop.subtypes[65535] = experimenter
+
+class max_rate(queue_desc_prop):
+    type = 2
+
+    def __init__(self, rate=None):
+        if rate != None:
+            self.rate = rate
+        else:
+            self.rate = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.rate))
+        packed.append('\x00' * 2)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = max_rate()
+        _type = reader.read("!H")[0]
+        assert(_type == 2)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.rate = reader.read("!H")[0]
+        reader.skip(2)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.rate != other.rate: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("max_rate {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("rate = ");
+                q.text("%#x" % self.rate)
+            q.breakable()
+        q.text('}')
+
+queue_desc_prop.subtypes[2] = max_rate
+
+class min_rate(queue_desc_prop):
+    type = 1
+
+    def __init__(self, rate=None):
+        if rate != None:
+            self.rate = rate
+        else:
+            self.rate = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!H", self.rate))
+        packed.append('\x00' * 2)
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        obj = min_rate()
+        _type = reader.read("!H")[0]
+        assert(_type == 1)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.rate = reader.read("!H")[0]
+        reader.skip(2)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.rate != other.rate: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("min_rate {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("rate = ");
+                q.text("%#x" % self.rate)
+            q.breakable()
+        q.text('}')
+
+queue_desc_prop.subtypes[1] = min_rate
+
+
diff --git a/Fabric/Utilities/src/python/loxi/of14/queue_stats_prop.py b/Fabric/Utilities/src/python/loxi/of14/queue_stats_prop.py
new file mode 100644
index 0000000..1e03c59
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of14/queue_stats_prop.py
@@ -0,0 +1,141 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of14']
+
+class queue_stats_prop(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = queue_stats_prop.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = queue_stats_prop()
+        obj.type = reader.read("!H")[0]
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("queue_stats_prop {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class experimenter(queue_stats_prop):
+    subtypes = {}
+
+    type = 65535
+
+    def __init__(self, experimenter=None, exp_type=None):
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if exp_type != None:
+            self.exp_type = exp_type
+        else:
+            self.exp_type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.exp_type))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 4)
+        subclass = experimenter.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = experimenter()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.experimenter = reader.read("!L")[0]
+        obj.exp_type = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.experimenter != other.experimenter: return False
+        if self.exp_type != other.exp_type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("exp_type = ");
+                q.text("%#x" % self.exp_type)
+            q.breakable()
+        q.text('}')
+
+queue_stats_prop.subtypes[65535] = experimenter
+
+
diff --git a/Fabric/Utilities/src/python/loxi/of14/role_prop.py b/Fabric/Utilities/src/python/loxi/of14/role_prop.py
new file mode 100644
index 0000000..b88f06f
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of14/role_prop.py
@@ -0,0 +1,141 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of14']
+
+class role_prop(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = role_prop.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = role_prop()
+        obj.type = reader.read("!H")[0]
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("role_prop {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+class experimenter(role_prop):
+    subtypes = {}
+
+    type = 65535
+
+    def __init__(self, experimenter=None, exp_type=None):
+        if experimenter != None:
+            self.experimenter = experimenter
+        else:
+            self.experimenter = 0
+        if exp_type != None:
+            self.exp_type = exp_type
+        else:
+            self.exp_type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        packed.append(struct.pack("!L", self.experimenter))
+        packed.append(struct.pack("!L", self.exp_type))
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!L', 4)
+        subclass = experimenter.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = experimenter()
+        _type = reader.read("!H")[0]
+        assert(_type == 65535)
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        obj.experimenter = reader.read("!L")[0]
+        obj.exp_type = reader.read("!L")[0]
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.experimenter != other.experimenter: return False
+        if self.exp_type != other.exp_type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("experimenter {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+                q.text("exp_type = ");
+                q.text("%#x" % self.exp_type)
+            q.breakable()
+        q.text('}')
+
+role_prop.subtypes[65535] = experimenter
+
+
diff --git a/Fabric/Utilities/src/python/loxi/of14/table_mod_prop.py b/Fabric/Utilities/src/python/loxi/of14/table_mod_prop.py
new file mode 100644
index 0000000..f6c4292
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of14/table_mod_prop.py
@@ -0,0 +1,80 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+
+# Automatically generated by LOXI from template module.py
+# Do not modify
+
+import struct
+import loxi
+import util
+import loxi.generic_util
+
+import sys
+ofp = sys.modules['loxi.of14']
+
+class table_mod_prop(loxi.OFObject):
+    subtypes = {}
+
+
+    def __init__(self, type=None):
+        if type != None:
+            self.type = type
+        else:
+            self.type = 0
+        return
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!H", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 1
+        length = sum([len(x) for x in packed])
+        packed[1] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        subclass = table_mod_prop.subtypes.get(subtype)
+        if subclass:
+            return subclass.unpack(reader)
+
+        obj = table_mod_prop()
+        obj.type = reader.read("!H")[0]
+        _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length, 4)
+        return obj
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.type != other.type: return False
+        return True
+
+    def pretty_print(self, q):
+        q.text("table_mod_prop {")
+        with q.group():
+            with q.indent(2):
+                q.breakable()
+            q.breakable()
+        q.text('}')
+
+
+
diff --git a/Fabric/Utilities/src/python/loxi/of14/util.py b/Fabric/Utilities/src/python/loxi/of14/util.py
new file mode 100644
index 0000000..fe23da1
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/of14/util.py
@@ -0,0 +1,139 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2011, 2012 Open Networking Foundation
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+# See the file LICENSE.pyloxi which should have been included in the source distribution
+# Automatically generated by LOXI from template util.py
+# Do not modify
+
+import struct
+import loxi
+import const
+import common
+import action
+import instruction
+import oxm
+import action_id
+import instruction_id
+import meter_band
+
+def pretty_mac(mac):
+    return ':'.join(["%02x" % x for x in mac])
+
+def pretty_ipv4(v):
+    return "%d.%d.%d.%d" % ((v >> 24) & 0xFF, (v >> 16) & 0xFF, (v >> 8) & 0xFF, v & 0xFF)
+
+def pretty_flags(v, flag_names):
+    set_flags = []
+    for flag_name in flag_names:
+        flag_value = getattr(const, flag_name)
+        if v & flag_value == flag_value:
+            set_flags.append(flag_name)
+        elif v & flag_value:
+            set_flags.append('%s&%#x' % (flag_name, v & flag_value))
+        v &= ~flag_value
+    if v:
+        set_flags.append("%#x" % v)
+    return '|'.join(set_flags) or '0'
+
+
+def pretty_port(v):
+    named_ports = [(k,v2) for (k,v2) in const.__dict__.iteritems() if k.startswith('OFPP_')]
+    for (k, v2) in named_ports:
+        if v == v2:
+            return k
+    return v
+
+def pack_port_no(value):
+    return struct.pack("!L", value)
+
+def unpack_port_no(reader):
+    return reader.read("!L")[0]
+
+def pack_fm_cmd(value):
+    return struct.pack("!B", value)
+
+def unpack_fm_cmd(reader):
+    return reader.read("!B")[0]
+
+def init_wc_bmap():
+    return 0
+
+def pack_wc_bmap(value):
+    return struct.pack("!Q", value)
+
+def unpack_wc_bmap(reader):
+    return reader.read("!Q")[0]
+
+def init_match_bmap():
+    return 0
+
+def pack_match_bmap(value):
+    return struct.pack("!Q", value)
+
+def unpack_match_bmap(reader):
+    return reader.read("!Q")[0]
+
+MASK64 = (1 << 64) - 1
+
+def pack_bitmap_128(value):
+    x = 0l
+    for y in value:
+        x |= 1 << y
+    return struct.pack("!QQ", (x >> 64) & MASK64, x & MASK64)
+
+def unpack_bitmap_128(reader):
+    hi, lo = reader.read("!QQ")
+    x = (hi << 64) | lo
+    i = 0
+    value = set()
+    while x != 0:
+        if x & 1 == 1:
+            value.add(i)
+        i += 1
+        x >>= 1
+    return value
+
+def pack_bitmap_512(value):
+    words = [0] * 8
+    for v in value:
+        assert v < 512
+        words[7-v/64] |= 1 << (v % 64)
+    return struct.pack("!8Q", *words)
+
+def unpack_bitmap_512(reader):
+    words = reader.read("!8Q")
+    x = 0l
+    for word in words:
+        x <<= 64
+        x |= word
+    i = 0
+    value = set()
+    while x != 0:
+        if x & 1 == 1:
+            value.add(i)
+        i += 1
+        x >>= 1
+    return value
+
+def pack_checksum_128(value):
+    return struct.pack("!QQ", (value >> 64) & MASK64, value & MASK64)
+
+def unpack_checksum_128(reader):
+    hi, lo = reader.read("!QQ")
+    return (hi << 64) | lo
diff --git a/Fabric/Utilities/src/python/loxi/pp.py b/Fabric/Utilities/src/python/loxi/pp.py
new file mode 100644
index 0000000..f85d1da
--- /dev/null
+++ b/Fabric/Utilities/src/python/loxi/pp.py
@@ -0,0 +1,266 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Copyright 2013, Big Switch Networks, Inc.
+
+"""
+pp - port of Ruby's PP library
+Also based on Lindig, C., & GbR, G. D. (2000). Strictly Pretty.
+
+Example usage:
+>>> import pp.pp as pp
+>>> print pp([[1, 2], [3, 4]], maxwidth=15)
+[
+  [ 1, 2 ],
+  [ 3, 4 ]
+]
+"""
+import unittest
+from contextlib import contextmanager
+
+def pp(obj, maxwidth=79):
+    """
+    Pretty-print the given object.
+    """
+    ctx = PrettyPrinter(maxwidth=maxwidth)
+    ctx.pp(obj)
+    return str(ctx)
+
+
+## Pretty-printers for builtin classes
+
+def pretty_print_list(pp, obj):
+    with pp.group():
+        pp.text('[')
+        with pp.indent(2):
+            for v in obj:
+                if not pp.first(): pp.text(',')
+                pp.breakable()
+                pp.pp(v)
+        pp.breakable()
+        pp.text(']')
+
+def pretty_print_dict(pp, obj):
+    with pp.group():
+        pp.text('{')
+        with pp.indent(2):
+            for (k, v) in sorted(obj.items()):
+                if not pp.first(): pp.text(',')
+                pp.breakable()
+                pp.pp(k)
+                pp.text(': ')
+                pp.pp(v)
+        pp.breakable()
+        pp.text('}')
+
+pretty_printers = {
+    list: pretty_print_list,
+    dict: pretty_print_dict,
+}
+
+
+## Implementation
+
+class PrettyPrinter(object):
+    def __init__(self, maxwidth):
+        self.maxwidth = maxwidth
+        self.cur_indent = 0
+        self.root_group = Group()
+        self.group_stack = [self.root_group]
+
+    def current_group(self):
+        return self.group_stack[-1]
+
+    def text(self, s):
+        self.current_group().append(str(s))
+
+    def breakable(self, sep=' '):
+        self.current_group().append(Breakable(sep, self.cur_indent))
+
+    def first(self):
+        return self.current_group().first()
+
+    @contextmanager
+    def indent(self, n):
+        self.cur_indent += n
+        yield
+        self.cur_indent -= n
+
+    @contextmanager
+    def group(self):
+        self.group_stack.append(Group())
+        yield
+        new_group = self.group_stack.pop()
+        self.current_group().append(new_group)
+
+    def pp(self, obj):
+        if hasattr(obj, "pretty_print"):
+            obj.pretty_print(self)
+        elif type(obj) in pretty_printers:
+            pretty_printers[type(obj)](self, obj)
+        else:
+            self.text(repr(obj))
+
+    def __str__(self):
+        return self.root_group.render(0, self.maxwidth)
+
+class Group(object):
+    __slots__ = ["fragments", "length", "_first"]
+
+    def __init__(self):
+        self.fragments = []
+        self.length = 0
+        self._first = True
+
+    def append(self, x):
+        self.fragments.append(x)
+        self.length += len(x)
+
+    def first(self):
+        if self._first:
+            self._first = False
+            return True
+        return False
+
+    def __len__(self):
+        return self.length
+
+    def render(self, curwidth, maxwidth):
+        dobreak = len(self) > (maxwidth - curwidth)
+
+        a = []
+        for x in self.fragments:
+            if isinstance(x, Breakable):
+                if dobreak:
+                    a.append('\n')
+                    a.append(' ' * x.indent)
+                    curwidth = 0
+                else:
+                    a.append(x.sep)
+            elif isinstance(x, Group):
+                a.append(x.render(curwidth, maxwidth))
+            else:
+                a.append(x)
+            curwidth += len(a[-1])
+        return ''.join(a)
+
+class Breakable(object):
+    __slots__ = ["sep", "indent"]
+
+    def __init__(self, sep, indent):
+        self.sep = sep
+        self.indent = indent
+
+    def __len__(self):
+        return len(self.sep)
+
+
+## Tests
+
+class TestPP(unittest.TestCase):
+    def test_scalars(self):
+        self.assertEquals(pp(1), "1")
+        self.assertEquals(pp("foo"), "'foo'")
+
+    def test_hash(self):
+        expected = """{ 1: 'a', 'b': 2 }"""
+        self.assertEquals(pp(eval(expected)), expected)
+        expected = """\
+{
+  1: 'a',
+  'b': 2
+}"""
+        self.assertEquals(pp(eval(expected), maxwidth=0), expected)
+
+    def test_array(self):
+        expected = """[ 1, 'a', 2 ]"""
+        self.assertEquals(pp(eval(expected)), expected)
+        expected = """\
+[
+  1,
+  'a',
+  2
+]"""
+        self.assertEquals(pp(eval(expected), maxwidth=0), expected)
+
+    def test_nested(self):
+        expected = """[ [ 1, 2 ], [ 3, 4 ] ]"""
+        self.assertEquals(pp(eval(expected)), expected)
+        expected = """\
+[
+  [
+    1,
+    2
+  ],
+  [
+    3,
+    4
+  ]
+]"""
+        self.assertEquals(pp(eval(expected), maxwidth=0), expected)
+
+    def test_breaking(self):
+        expected = """\
+[
+  [ 1, 2 ],
+  'abcdefghijklmnopqrstuvwxyz'
+]"""
+        self.assertEquals(pp(eval(expected), maxwidth=24), expected)
+        expected = """\
+[
+  [ 'abcd', 2 ],
+  [ '0123456789' ],
+  [
+    '0123456789',
+    'abcdefghij'
+  ],
+  [ 'abcdefghijklmnop' ],
+  [
+    'abcdefghijklmnopq'
+  ],
+  { 'k': 'v' },
+  {
+    1: [ 2, [ 3, 4 ] ],
+    'foo': 'abcdefghijklmnop'
+  }
+]"""
+        self.assertEquals(pp(eval(expected), maxwidth=24), expected)
+        expected = """\
+[
+  [ 1, 2 ],
+  [ 3, 4 ]
+]"""
+        self.assertEquals(pp(eval(expected), maxwidth=15), expected)
+
+    # This is an edge case where our simpler algorithm breaks down.
+    @unittest.expectedFailure
+    def test_greedy_breaking(self):
+        expected = """\
+abc def
+ghijklmnopqrstuvwxyz\
+"""
+        pp = PrettyPrinter(maxwidth=8)
+        pp.text("abc")
+        with pp.group():
+            pp.breakable()
+        pp.text("def")
+        with pp.group():
+            pp.breakable()
+        pp.text("ghijklmnopqrstuvwxyz")
+        self.assertEquals(str(pp), expected)
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/Fabric/Utilities/src/python/oftest/__init__.py b/Fabric/Utilities/src/python/oftest/__init__.py
new file mode 100644
index 0000000..2be5038
--- /dev/null
+++ b/Fabric/Utilities/src/python/oftest/__init__.py
@@ -0,0 +1,56 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+'''Docstring to silence pylint; ignores --ignore option for __init__.py'''
+import sys
+import os
+import logging
+
+# Global config dictionary
+# Populated by oft.
+config = {}
+
+# Global DataPlane instance used by all tests.
+# Populated by oft.
+dataplane_instance = None
+
+def open_logfile(name):
+    """
+    (Re)open logfile
+
+    When using a log directory a new logfile is created for each test. The same
+    code is used to implement a single logfile in the absence of --log-dir.
+    """
+
+    _format = "%(asctime)s.%(msecs)03d  %(name)-10s: %(levelname)-8s: %(message)s"
+    _datefmt = "%H:%M:%S"
+
+    if config["log_dir"] != None:
+        filename = os.path.join(config["log_dir"], name) + ".log"
+    else:
+        filename = config["log_file"]
+
+    logger = logging.getLogger()
+
+    # Remove any existing handlers
+    for handler in logger.handlers:
+        logger.removeHandler(handler)
+        handler.close()
+
+    # Add a new handler
+    handler = logging.FileHandler(filename, mode='a')
+    handler.setFormatter(logging.Formatter(_format, _datefmt))
+    logger.addHandler(handler)
diff --git a/Fabric/Utilities/src/python/oftest/afpacket.py b/Fabric/Utilities/src/python/oftest/afpacket.py
new file mode 100644
index 0000000..a891d85
--- /dev/null
+++ b/Fabric/Utilities/src/python/oftest/afpacket.py
@@ -0,0 +1,128 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+"""
+AF_PACKET receive support
+
+When VLAN offload is enabled on the NIC Linux will not deliver the VLAN tag
+in the data returned by recv. Instead, it delivers the VLAN TCI in a control
+message. Python 2.x doesn't have built-in support for recvmsg, so we have to
+use ctypes to call it. The recv function exported by this module reconstructs
+the VLAN tag if it was offloaded.
+"""
+
+import socket
+import struct
+from ctypes import *
+
+ETH_P_8021Q = 0x8100
+SOL_PACKET = 263
+PACKET_AUXDATA = 8
+TP_STATUS_VLAN_VALID = 1 << 4
+
+class struct_iovec(Structure):
+    _fields_ = [
+        ("iov_base", c_void_p),
+        ("iov_len", c_size_t),
+    ]
+
+class struct_msghdr(Structure):
+    _fields_ = [
+        ("msg_name", c_void_p),
+        ("msg_namelen", c_uint32),
+        ("msg_iov", POINTER(struct_iovec)),
+        ("msg_iovlen", c_size_t),
+        ("msg_control", c_void_p),
+        ("msg_controllen", c_size_t),
+        ("msg_flags", c_int),
+    ]
+
+class struct_cmsghdr(Structure):
+    _fields_ = [
+        ("cmsg_len", c_size_t),
+        ("cmsg_level", c_int),
+        ("cmsg_type", c_int),
+    ]
+
+class struct_tpacket_auxdata(Structure):
+    _fields_ = [
+        ("tp_status", c_uint),
+        ("tp_len", c_uint),
+        ("tp_snaplen", c_uint),
+        ("tp_mac", c_ushort),
+        ("tp_net", c_ushort),
+        ("tp_vlan_tci", c_ushort),
+        ("tp_padding", c_ushort),
+    ]
+
+libc = CDLL("libc.so.6")
+recvmsg = libc.recvmsg
+recvmsg.argtypes = [c_int, POINTER(struct_msghdr), c_int]
+recvmsg.retype = c_int
+
+def enable_auxdata(sk):
+    """
+    Ask the kernel to return the VLAN tag in a control message
+
+    Must be called on the socket before afpacket.recv.
+    """
+    sk.setsockopt(SOL_PACKET, PACKET_AUXDATA, 1)
+
+def recv(sk, bufsize):
+    """
+    Receive a packet from an AF_PACKET socket
+    @sk Socket
+    @bufsize Maximum packet size
+    """
+    buf = create_string_buffer(bufsize)
+
+    ctrl_bufsize = sizeof(struct_cmsghdr) + sizeof(struct_tpacket_auxdata) + sizeof(c_size_t)
+    ctrl_buf = create_string_buffer(ctrl_bufsize)
+
+    iov = struct_iovec()
+    iov.iov_base = cast(buf, c_void_p)
+    iov.iov_len = bufsize
+
+    msghdr = struct_msghdr()
+    msghdr.msg_name = None
+    msghdr.msg_namelen = 0
+    msghdr.msg_iov = pointer(iov)
+    msghdr.msg_iovlen = 1
+    msghdr.msg_control = cast(ctrl_buf, c_void_p)
+    msghdr.msg_controllen = ctrl_bufsize
+    msghdr.msg_flags = 0
+
+    rv = recvmsg(sk.fileno(), byref(msghdr), 0)
+    if rv < 0:
+        raise RuntimeError("recvmsg failed: rv=%d", rv)
+
+    # The kernel only delivers control messages we ask for. We
+    # only enabled PACKET_AUXDATA, so we can assume it's the
+    # only control message.
+    assert msghdr.msg_controllen >= sizeof(struct_cmsghdr)
+
+    cmsghdr = struct_cmsghdr.from_buffer(ctrl_buf) # pylint: disable=E1101
+    assert cmsghdr.cmsg_level == SOL_PACKET
+    assert cmsghdr.cmsg_type == PACKET_AUXDATA
+
+    auxdata = struct_tpacket_auxdata.from_buffer(ctrl_buf, sizeof(struct_cmsghdr)) # pylint: disable=E1101
+
+    if auxdata.tp_vlan_tci != 0 or auxdata.tp_status & TP_STATUS_VLAN_VALID:
+        # Insert VLAN tag
+        tag = struct.pack("!HH", ETH_P_8021Q, auxdata.tp_vlan_tci)
+        return buf.raw[:12] + tag + buf.raw[12:rv]
+    else:
+        return buf.raw[:rv]
diff --git a/Fabric/Utilities/src/python/oftest/base_tests.py b/Fabric/Utilities/src/python/oftest/base_tests.py
new file mode 100755
index 0000000..7eb68bc
--- /dev/null
+++ b/Fabric/Utilities/src/python/oftest/base_tests.py
@@ -0,0 +1,162 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+"""
+Base classes for test cases
+
+Tests will usually inherit from one of these classes to have the controller
+and/or dataplane automatically set up.
+"""
+
+import logging
+import unittest
+import os
+
+import oftest
+from oftest import config
+import oftest.controller as controller
+import oftest.dataplane as dataplane
+import ofp
+from ofdpa_utils import *
+
+class BaseTest(unittest.TestCase):
+    def __str__(self):
+        return self.id().replace('.runTest', '')
+
+    def setUp(self):
+        if config["force_ofdpa_restart"]:
+            logging.info("Restarting OFDPA")
+            forceOfdpaRestart( config["force_ofdpa_restart"]);
+        oftest.open_logfile(str(self))
+        logging.info("** START TEST CASE " + str(self))
+
+    def tearDown(self):
+        logging.info("** END TEST CASE " + str(self))
+        if config["force_ofdpa_restart"]:
+            forceOfdpaStop( config["force_ofdpa_restart"]);
+
+
+class SimpleProtocol(BaseTest):
+    """
+    Root class for setting up the controller
+    """
+
+    def setUp(self):
+        BaseTest.setUp(self)
+        self.controller = controller.Controller(
+            switch=config["switch_ip"],
+            host=config["controller_host"],
+            port=config["controller_port"])
+        self.controller.start()
+
+        try:
+            #@todo Add an option to wait for a pkt transaction to ensure version
+            # compatibilty?
+            self.controller.connect(timeout=20)
+
+            # By default, respond to echo requests
+            self.controller.keep_alive = True
+            if not self.controller.active:
+                raise Exception("Controller startup failed")
+            if self.controller.switch_addr is None:
+                raise Exception("Controller startup failed (no switch addr)")
+            logging.info("Connected " + str(self.controller.switch_addr))
+            request = ofp.message.features_request()
+            reply, pkt = self.controller.transact(request)
+            self.assertTrue(reply is not None,
+                            "Did not complete features_request for handshake")
+            if reply.version == 1:
+                self.supported_actions = reply.actions
+                logging.info("Supported actions: " + hex(self.supported_actions))
+        except:
+            self.controller.kill()
+            del self.controller
+            raise
+
+    def inheritSetup(self, parent):
+        """
+        Inherit the setup of a parent
+
+        This allows running at test from within another test.  Do the
+        following:
+
+        sub_test = SomeTestClass()  # Create an instance of the test class
+        sub_test.inheritSetup(self) # Inherit setup of parent
+        sub_test.runTest()          # Run the test
+
+        Normally, only the parent's setUp and tearDown are called and
+        the state after the sub_test is run must be taken into account
+        by subsequent operations.
+        """
+        logging.info("** Setup " + str(self) + " inheriting from "
+                          + str(parent))
+        self.controller = parent.controller
+        self.supported_actions = parent.supported_actions
+        
+    def tearDown(self):
+        self.controller.shutdown()
+        self.controller.join()
+        del self.controller
+        BaseTest.tearDown(self)
+
+    def assertTrue(self, cond, msg):
+        if not cond:
+            logging.error("** FAILED ASSERTION: " + msg)
+        unittest.TestCase.assertTrue(self, cond, msg)
+
+class SimpleDataPlane(SimpleProtocol):
+    """
+    Root class that sets up the controller and dataplane
+    """
+    def setUp(self):
+        SimpleProtocol.setUp(self)
+        self.dataplane = oftest.dataplane_instance
+        self.dataplane.flush()
+        if config["log_dir"] != None:
+            filename = os.path.join(config["log_dir"], str(self)) + ".pcap"
+            self.dataplane.start_pcap(filename)
+
+    def inheritSetup(self, parent):
+        """
+        Inherit the setup of a parent
+
+        See SimpleProtocol.inheritSetup
+        """
+        SimpleProtocol.inheritSetup(self, parent)
+        self.dataplane = parent.dataplane
+
+    def tearDown(self):
+        if config["log_dir"] != None:
+            self.dataplane.stop_pcap()
+        SimpleProtocol.tearDown(self)
+
+class DataPlaneOnly(BaseTest):
+    """
+    Root class that sets up only the dataplane
+    """
+
+    def setUp(self):
+        BaseTest.setUp(self)
+        self.dataplane = oftest.dataplane_instance
+        self.dataplane.flush()
+        if config["log_dir"] != None:
+            filename = os.path.join(config["log_dir"], str(self)) + ".pcap"
+            self.dataplane.start_pcap(filename)
+
+    def tearDown(self):
+        if config["log_dir"] != None:
+            self.dataplane.stop_pcap()
+        BaseTest.tearDown(self)
diff --git a/Fabric/Utilities/src/python/oftest/controller.py b/Fabric/Utilities/src/python/oftest/controller.py
new file mode 100755
index 0000000..e52bfbe
--- /dev/null
+++ b/Fabric/Utilities/src/python/oftest/controller.py
@@ -0,0 +1,767 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+"""
+OpenFlow Test Framework
+
+Controller class
+
+Provide the interface to the control channel to the switch under test.  
+
+Class inherits from thread so as to run in background allowing
+asynchronous callbacks (if needed, not required).  Also supports
+polling.
+
+The controller thread maintains a queue.  Incoming messages that
+are not handled by a callback function are placed in this queue for 
+poll calls.  
+
+Callbacks and polling support specifying the message type
+
+@todo Support transaction semantics via xid
+@todo Support select and listen on an administrative socket (or
+use a timeout to support clean shutdown).
+
+Currently only one connection is accepted during the life of
+the controller.   There seems
+to be no clean way to interrupt an accept call.  Using select that also listens
+on an administrative socket and can shut down the socket might work.
+
+"""
+
+import sys
+import os
+import socket
+import time
+import struct
+import select
+import logging
+from threading import Thread
+from threading import Lock
+from threading import Condition
+
+import ofutils
+import loxi
+
+# Configured openflow version
+import ofp as cfg_ofp
+
+FILTER = ''.join( [ (len( repr( chr( x ) ) ) == 3) and chr( x ) or '.'
+                    for x in range( 256 ) ] )
+
+
+def hex_dump_buffer( src, length=16 ):
+    """
+    Convert src to a hex dump string and return the string
+    @param src The source buffer
+    @param length The number of bytes shown in each line
+    @returns A string showing the hex dump
+    """
+    result = [ "\n" ]
+    for i in xrange( 0, len( src ), length ):
+        chars = src[ i:i + length ]
+        hex = ' '.join( [ "%02x" % ord( x ) for x in chars ] )
+        printable = ''.join( [ "%s" % ((ord( x ) <= 127 and
+                                        FILTER[ ord( x ) ]) or '.') for x in
+                               chars ] )
+        result.append( "%04x  %-*s  %s\n" % (i, length * 3, hex, printable) )
+    return ''.join( result )
+
+
+##@todo Find a better home for these identifiers (controller)
+RCV_SIZE_DEFAULT = 32768
+LISTEN_QUEUE_SIZE = 1
+
+
+class Controller( Thread ):
+    """
+    Class abstracting the control interface to the switch.  
+
+    For receiving messages, two mechanism will be implemented.  First,
+    query the interface with poll.  Second, register to have a
+    function called by message type.  The callback is passed the
+    message type as well as the raw packet (or message object)
+
+    One of the main purposes of this object is to translate between network 
+    and host byte order.  'Above' this object, things should be in host
+    byte order.
+
+    @todo Consider using SocketServer for listening socket
+    @todo Test transaction code
+
+    @var rcv_size The receive size to use for receive calls
+    @var max_pkts The max size of the receive queue
+    @var keep_alive If true, listen for echo requests and respond w/
+    echo replies
+    @var initial_hello If true, will send a hello message immediately
+    upon connecting to the switch
+    @var switch If not None, do an active connection to the switch
+    @var host The host to use for connect
+    @var port The port to connect on 
+    @var packets_total Total number of packets received
+    @var packets_expired Number of packets popped from queue as queue full
+    @var packets_handled Number of packets handled by something
+    @var dbg_state Debug indication of state
+    """
+
+    def __init__( self, switch=None, host='127.0.0.1', port=6653, max_pkts=1024,
+                  force=False ):
+        Thread.__init__( self )
+        # Socket related
+        self.rcv_size = RCV_SIZE_DEFAULT
+        self.listen_socket = None
+        self.switch_socket = None
+        self.switch_addr = None
+        self.connect_cv = Condition( )
+        self.message_cv = Condition( )
+        self.tx_lock = Lock( )
+
+        # Used to wake up the event loop from another thread
+        self.waker = ofutils.EventDescriptor( )
+
+        # Counters
+        self.socket_errors = 0
+        self.parse_errors = 0
+        self.packets_total = 0
+        self.packets_expired = 0
+        self.packets_handled = 0
+        self.poll_discards = 0
+
+        # State
+        self.sync = Lock( )
+        self.handlers = { }
+        self.keep_alive = False
+        self.active = True
+        self.initial_hello = True
+
+        # OpenFlow message/packet queue
+        # Protected by the packets_cv lock / condition variable
+        self.packets = [ ]
+        self.packets_cv = Condition( )
+        self.packet_in_count = 0
+
+        # Settings
+        self.max_pkts = max_pkts
+        self.switch = switch
+        self.passive = not self.switch
+        self.force = force
+        self.host = host
+        self.port = port
+        self.dbg_state = "init"
+        self.logger = logging.getLogger( "controller" )
+        self.filter_packet_in = False  # Drop "excessive" packet ins
+        self.pkt_in_run = 0  # Count on run of packet ins
+        self.pkt_in_filter_limit = 50  # Count on run of packet ins
+        self.pkt_in_dropped = 0  # Total dropped packet ins
+        self.transact_to = 15  # Transact timeout default value; add to config
+
+        # Transaction and message type waiting variables 
+        #   xid_cv: Condition variable (semaphore) for packet waiters
+        #   xid: Transaction ID being waited on
+        #   xid_response: Transaction response message
+        self.xid_cv = Condition( )
+        self.xid = None
+        self.xid_response = None
+
+        self.buffered_input = ""
+
+        # Create listen socket
+        if self.passive:
+            self.logger.info( "Create/listen at " + self.host + ":" +
+                              str( self.port ) )
+            ai = socket.getaddrinfo( self.host, self.port, socket.AF_UNSPEC,
+                                     socket.SOCK_STREAM, 0, socket.AI_PASSIVE )
+            # Use first returned addrinfo
+            (family, socktype, proto, name, sockaddr) = ai[ 0 ]
+            self.listen_socket = socket.socket( family, socktype )
+            self.listen_socket.setsockopt( socket.SOL_SOCKET,
+                                           socket.SO_REUSEADDR, 1 )
+            self.listen_socket.bind( sockaddr )
+            self.listen_socket.listen( LISTEN_QUEUE_SIZE )
+
+    def filter_packet( self, rawmsg, hdr ):
+        """
+        Check if packet should be filtered
+
+        Currently filters packet in messages
+        @return Boolean, True if packet should be dropped
+        """
+        # XXX didn't actually check for packet-in...
+        return False
+        # Add check for packet in and rate limit
+        if self.filter_packet_in:
+            # If we were dropping packets, report number dropped
+            # TODO dont drop expected packet ins
+            if self.pkt_in_run > self.pkt_in_filter_limit:
+                self.logger.debug( "Dropped %d packet ins (%d total)"
+                                   % ((self.pkt_in_run -
+                                       self.pkt_in_filter_limit),
+                                      self.pkt_in_dropped) )
+            self.pkt_in_run = 0
+
+        return False
+
+    def _pkt_handle( self, pkt ):
+        """
+        Check for all packet handling conditions
+
+        Parse and verify message 
+        Check if XID matches something waiting
+        Check if message is being expected for a poll operation
+        Check if keep alive is on and message is an echo request
+        Check if any registered handler wants the packet
+        Enqueue if none of those conditions is met
+
+        an echo request in case keep_alive is true, followed by
+        registered message handlers.
+        @param pkt The raw packet (string) which may contain multiple OF msgs
+        """
+
+        # snag any left over data from last read()
+        pkt = self.buffered_input + pkt
+        self.buffered_input = ""
+
+        # Process each of the OF msgs inside the pkt
+        offset = 0
+        while offset < len( pkt ):
+            if offset + 8 > len( pkt ):
+                break
+
+            # Parse the header to get type
+            hdr_version, hdr_type, hdr_length, hdr_xid = cfg_ofp.message.parse_header(
+                    pkt[ offset: ] )
+
+            # Use loxi to resolve to ofp of matching version
+            ofp = loxi.protocol( hdr_version )
+
+            # Extract the raw message bytes
+            if (offset + hdr_length) > len( pkt ):
+                break
+            rawmsg = pkt[ offset: offset + hdr_length ]
+            offset += hdr_length
+
+            # if self.filter_packet(rawmsg, hdr):
+            #    continue
+
+            msg = ofp.message.parse_message( rawmsg )
+            if not msg:
+                self.parse_errors += 1
+                self.logger.warn( "Could not parse message" )
+                continue
+
+            self.logger.debug( "Msg in: version %d class %s len %d xid %d",
+                               hdr_version, type( msg ).__name__, hdr_length,
+                               hdr_xid )
+
+            with self.sync:
+                # Check if transaction is waiting
+                with self.xid_cv:
+                    if self.xid and hdr_xid == self.xid:
+                        self.logger.debug(
+                                "Matched expected XID " + str( hdr_xid ) )
+                        self.xid_response = (msg, rawmsg)
+                        self.xid = None
+                        self.xid_cv.notify( )
+                        continue
+
+                # Check if keep alive is set; if so, respond to echo requests
+                if self.keep_alive:
+                    if hdr_type == ofp.OFPT_ECHO_REQUEST:
+                        self.logger.debug( "Responding to echo request" )
+                        rep = ofp.message.echo_reply( )
+                        rep.xid = hdr_xid
+                        # Ignoring additional data
+                        self.message_send( rep )
+                        continue
+
+                # Generalize to counters for all packet types?
+                if msg.type == ofp.OFPT_PACKET_IN:
+                    self.packet_in_count += 1
+
+                # Log error messages
+                if isinstance( msg, ofp.message.error_msg ):
+                    # pylint: disable=E1103
+                    if msg.err_type in ofp.ofp_error_type_map:
+                        type_str = ofp.ofp_error_type_map[ msg.err_type ]
+                        if msg.err_type == ofp.OFPET_HELLO_FAILED:
+                            code_map = ofp.ofp_hello_failed_code_map
+                        elif msg.err_type == ofp.OFPET_BAD_REQUEST:
+                            code_map = ofp.ofp_bad_request_code_map
+                        elif msg.err_type == ofp.OFPET_BAD_ACTION:
+                            code_map = ofp.ofp_bad_action_code_map
+                        elif msg.err_type == ofp.OFPET_FLOW_MOD_FAILED:
+                            code_map = ofp.ofp_flow_mod_failed_code_map
+                        elif msg.err_type == ofp.OFPET_PORT_MOD_FAILED:
+                            code_map = ofp.ofp_port_mod_failed_code_map
+                        elif msg.err_type == ofp.OFPET_QUEUE_OP_FAILED:
+                            code_map = ofp.ofp_queue_op_failed_code_map
+                        else:
+                            code_map = None
+
+                        if code_map and msg.code in code_map:
+                            code_str = code_map[ msg.code ]
+                        else:
+                            code_str = "unknown"
+                    else:
+                        type_str = "unknown"
+                        code_str = "unknown"
+                    self.logger.warn(
+                            "Received error message: xid=%d type=%s (%d) code=%s (%d)",
+                            hdr_xid, type_str, msg.err_type, code_str,
+                            msg.code )
+
+                # Now check for message handlers; preference is given to
+                # handlers for a specific packet
+                handled = False
+                if hdr_type in self.handlers.keys( ):
+                    handled = self.handlers[ hdr_type ]( self, msg, rawmsg )
+                if not handled and ("all" in self.handlers.keys( )):
+                    handled = self.handlers[ "all" ]( self, msg, rawmsg )
+
+                if not handled:  # Not handled, enqueue
+                    with self.packets_cv:
+                        if len( self.packets ) >= self.max_pkts:
+                            self.packets.pop( 0 )
+                            self.packets_expired += 1
+                        self.packets.append( (msg, rawmsg) )
+                        self.packets_cv.notify_all( )
+                    self.packets_total += 1
+                else:
+                    self.packets_handled += 1
+                    self.logger.debug( "Message handled by callback" )
+
+        # end of 'while offset < len(pkt)'
+        #   note that if offset = len(pkt), this is
+        #   appends a harmless empty string
+        self.buffered_input += pkt[ offset: ]
+
+    def _socket_ready_handle( self, s ):
+        """
+        Handle an input-ready socket
+
+        @param s The socket object that is ready
+        @returns 0 on success, -1 on error
+        """
+
+        if self.passive and s and s == self.listen_socket:
+            if self.switch_socket:
+                self.logger.warning(
+                        "Ignoring incoming connection; already connected to switch" )
+                (sock, addr) = self.listen_socket.accept( )
+                sock.close( )
+                return 0
+
+            try:
+                (sock, addr) = self.listen_socket.accept( )
+            except:
+                self.logger.warning( "Error on listen socket accept" )
+                return -1
+            self.logger.info( self.host + ":" + str(
+                    self.port ) + ": Incoming connection from " + str( addr ) )
+
+            with self.connect_cv:
+                (self.switch_socket, self.switch_addr) = (sock, addr)
+                self.switch_socket.setsockopt( socket.IPPROTO_TCP,
+                                               socket.TCP_NODELAY, True )
+                if self.initial_hello:
+                    self.message_send( cfg_ofp.message.hello( ) )
+                self.connect_cv.notify( )  # Notify anyone waiting
+
+            # Prevent further connections
+            self.listen_socket.close( )
+            self.listen_socket = None
+        elif s and s == self.switch_socket:
+            for idx in range( 3 ):  # debug: try a couple of times
+                try:
+                    pkt = self.switch_socket.recv( self.rcv_size )
+                except:
+                    self.logger.warning( "Error on switch read" )
+                    return -1
+
+                if not self.active:
+                    return 0
+
+                if len( pkt ) == 0:
+                    self.logger.warning( "Zero-length switch read, %d" % idx )
+                else:
+                    break
+
+            if len( pkt ) == 0:  # Still no packet
+                self.logger.warning( "Zero-length switch read; closing cxn" )
+                self.logger.info( str( self ) )
+                return -1
+
+            self._pkt_handle( pkt )
+        elif s and s == self.waker:
+            self.waker.wait( )
+        else:
+            self.logger.error( "Unknown socket ready: " + str( s ) )
+            return -1
+
+        return 0
+
+    def active_connect( self ):
+        """
+        Actively connect to a switch IP addr
+        """
+        try:
+            self.logger.info( "Trying active connection to %s" % self.switch )
+            soc = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
+            soc.connect( (self.switch, self.port) )
+            self.logger.info( "Connected to " + self.switch + " on " +
+                              str( self.port ) )
+            soc.setsockopt( socket.IPPROTO_TCP, socket.TCP_NODELAY, True )
+            self.switch_addr = (self.switch, self.port)
+            return soc
+        except (StandardError, socket.error), e:
+            self.logger.error( "Could not connect to %s at %d:: %s" %
+                               (self.switch, self.port, str( e )) )
+        return None
+
+    def wakeup( self ):
+        """
+        Wake up the event loop, presumably from another thread.
+        """
+        self.waker.notify( )
+
+    def sockets( self ):
+        """
+        Return list of sockets to select on.
+        """
+        socs = [ self.listen_socket, self.switch_socket, self.waker ]
+        return [ x for x in socs if x ]
+
+    def run( self ):
+        """
+        Activity function for class
+
+        Assumes connection to switch already exists.  Listens on
+        switch_socket for messages until an error (or zero len pkt)
+        occurs.
+
+        When there is a message on the socket, check for handlers; queue the
+        packet if no one handles the packet.
+
+        See note for controller describing the limitation of a single
+        connection for now.
+        """
+
+        self.dbg_state = "running"
+
+        while self.active:
+            try:
+                sel_in, sel_out, sel_err = \
+                    select.select( self.sockets( ), [ ], self.sockets( ), 1 )
+            except:
+                print sys.exc_info( )
+                self.logger.error( "Select error, disconnecting" )
+                self.disconnect( )
+
+            for s in sel_err:
+                self.logger.error(
+                        "Got socket error on: " + str( s ) + ", disconnecting" )
+                self.disconnect( )
+
+            for s in sel_in:
+                if self._socket_ready_handle( s ) == -1:
+                    self.disconnect( )
+
+        # End of main loop
+        self.dbg_state = "closing"
+        self.logger.info( "Exiting controller thread" )
+        self.shutdown( )
+
+    def connect( self, timeout=-1 ):
+        """
+        Connect to the switch
+
+        @param timeout Block for up to timeout seconds. Pass -1 for the default.
+        @return Boolean, True if connected
+        """
+
+        if not self.passive:  # Do active connection now
+            self.logger.info( "Attempting to connect to %s on port %s" %
+                                  (self.switch, str( self.port )) )
+            soc = self.active_connect( )
+            if soc:
+                self.logger.info( "Connected to %s", self.switch )
+                self.dbg_state = "running"
+                self.switch_socket = soc
+                self.wakeup( )
+                with self.connect_cv:
+                    if self.initial_hello:
+                        self.message_send( cfg_ofp.message.hello( ) )
+                    self.connect_cv.notify( )  # Notify anyone waiting
+            else:
+                self.logger.error( "Could not actively connect to switch %s",
+                                   self.switch )
+                self.active = False
+        else:
+            with self.connect_cv:
+                ofutils.timed_wait( self.connect_cv, lambda: self.switch_socket,
+                                    timeout=timeout )
+
+        return self.switch_socket is not None
+
+    def disconnect( self, timeout=-1 ):
+        """
+        If connected to a switch, disconnect.
+        """
+        if self.switch_socket:
+            self.switch_socket.close( )
+            self.switch_socket = None
+            self.switch_addr = None
+            with self.packets_cv:
+                self.packets = [ ]
+            with self.connect_cv:
+                self.connect_cv.notifyAll( )
+
+    def wait_disconnected( self, timeout=-1 ):
+        """
+        @param timeout Block for up to timeout seconds. Pass -1 for the default.
+        @return Boolean, True if disconnected
+        """
+
+        with self.connect_cv:
+            ofutils.timed_wait( self.connect_cv,
+                                lambda: True if not self.switch_socket else None,
+                                timeout=timeout )
+        return self.switch_socket is None
+
+    def kill( self ):
+        """
+        Force the controller thread to quit
+        """
+        self.active = False
+        self.wakeup( )
+        self.join( )
+
+    def shutdown( self ):
+        """
+        Shutdown the controller closing all sockets
+
+        @todo Might want to synchronize shutdown with self.sync...
+        """
+
+        self.active = False
+        try:
+            self.switch_socket.shutdown( socket.SHUT_RDWR )
+        except:
+            self.logger.info( "Ignoring switch soc shutdown error" )
+        self.switch_socket = None
+
+        try:
+            self.listen_socket.shutdown( socket.SHUT_RDWR )
+        except:
+            self.logger.info( "Ignoring listen soc shutdown error" )
+        self.listen_socket = None
+
+        # Wakeup condition variables on which controller may be wait
+        with self.xid_cv:
+            self.xid_cv.notifyAll( )
+
+        with self.connect_cv:
+            self.connect_cv.notifyAll( )
+
+        self.wakeup( )
+        self.dbg_state = "down"
+
+    def register( self, msg_type, handler ):
+        """
+        Register a callback to receive a specific message type.
+
+        Only one handler may be registered for a given message type.
+
+        WARNING:  A lock is held during the handler call back, so 
+        the handler should not make any blocking calls
+
+        @param msg_type The type of message to receive.  May be DEFAULT 
+        for all non-handled packets.  The special type, the string "all"
+        will send all packets to the handler.
+        @param handler The function to call when a message of the given 
+        type is received.
+        """
+        # Should check type is valid
+        if not handler and msg_type in self.handlers.keys( ):
+            del self.handlers[ msg_type ]
+            return
+        self.handlers[ msg_type ] = handler
+
+    def poll( self, exp_msg=None, timeout=-1 ):
+        """
+        Wait for the next OF message received from the switch.
+
+        @param exp_msg If set, return only when this type of message 
+        is received (unless timeout occurs).
+
+        @param timeout Maximum number of seconds to wait for the message.
+        Pass -1 for the default timeout.
+
+        @retval A pair (msg, pkt) where msg is a message object and pkt
+        the string representing the packet as received from the socket.
+        This allows additional parsing by the receiver if necessary.
+
+        The data members in the message are in host endian order.
+        If an error occurs, (None, None) is returned
+        """
+
+        if exp_msg is None:
+            self.logger.warn( "DEPRECATED polling for any message class" )
+            klass = None
+        elif isinstance( exp_msg, int ):
+            klass = cfg_ofp.message.message.subtypes[ exp_msg ]
+        elif issubclass( exp_msg, loxi.OFObject ):
+            klass = exp_msg
+        else:
+            raise ValueError( "Unexpected exp_msg argument %r" % exp_msg )
+
+        self.logger.debug( "Polling for %s", klass.__name__ )
+
+        # Take the packet from the queue
+        def grab( ):
+            for i, (msg, pkt) in enumerate( self.packets ):
+                if klass is None or isinstance( msg, klass ):
+                    self.logger.debug( "Got %s message",
+                                       msg.__class__.__name__ )
+                    return self.packets.pop( i )
+            # Not found
+            self.logger.debug( "%s message not in queue", klass.__name__ )
+            return None
+
+        with self.packets_cv:
+            ret = ofutils.timed_wait( self.packets_cv, grab, timeout=timeout )
+
+        if ret != None:
+            (msg, pkt) = ret
+            return (msg, pkt)
+        else:
+            return (None, None)
+
+    def transact( self, msg, timeout=-1 ):
+        """
+        Run a message transaction with the switch
+
+        Send the message in msg and wait for a reply with a matching
+        transaction id.  Transactions have the highest priority in
+        received message handling.
+
+        @param msg The message object to send; must not be a string
+        @param timeout The timeout in seconds; if -1 use default.
+        """
+
+        if msg.xid == None:
+            msg.xid = ofutils.gen_xid( )
+
+        self.logger.debug( "Running transaction %d" % msg.xid )
+
+        with self.xid_cv:
+            if self.xid:
+                self.logger.error( "Can only run one transaction at a time" )
+                return (None, None)
+
+            self.xid = msg.xid
+            self.xid_response = None
+            self.message_send( msg )
+
+            self.logger.debug( "Waiting for transaction %d" % msg.xid )
+            ofutils.timed_wait( self.xid_cv, lambda: self.xid_response,
+                                timeout=timeout )
+
+            if self.xid_response:
+                (resp, pkt) = self.xid_response
+                self.xid_response = None
+            else:
+                (resp, pkt) = (None, None)
+
+        if resp is None:
+            self.logger.warning( "No response for xid " + str( self.xid ) )
+        return (resp, pkt)
+
+    def message_send( self, msg ):
+        """
+        Send the message to the switch
+
+        @param msg A string or OpenFlow message object to be forwarded to
+        the switch.
+        """
+        if not self.switch_socket:
+            # Sending a string indicates the message is ready to go
+            raise Exception( "no socket" )
+
+        if msg.xid == None:
+            msg.xid = ofutils.gen_xid( )
+
+        outpkt = msg.pack( )
+
+        self.logger.debug( "Msg out: version %d class %s len %d xid %d",
+                           msg.version, type( msg ).__name__, len( outpkt ),
+                           msg.xid )
+
+        with self.tx_lock:
+            if self.switch_socket.sendall( outpkt ) is not None:
+                raise AssertionError( "failed to send message to switch" )
+
+        return 0  # for backwards compatibility
+
+    def clear_queue( self ):
+        """
+        Clear the input queue and report the number of messages
+        that were in it
+        """
+        enqueued_pkt_count = len( self.packets )
+        with self.packets_cv:
+            self.packets = [ ]
+        return enqueued_pkt_count
+
+    def __str__( self ):
+        string = "Controller:\n"
+        string += "  state           " + self.dbg_state + "\n"
+        string += "  switch_addr     " + str( self.switch_addr ) + "\n"
+        string += "  pending pkts    " + str( len( self.packets ) ) + "\n"
+        string += "  total pkts      " + str( self.packets_total ) + "\n"
+        string += "  expired pkts    " + str( self.packets_expired ) + "\n"
+        string += "  handled pkts    " + str( self.packets_handled ) + "\n"
+        string += "  poll discards   " + str( self.poll_discards ) + "\n"
+        string += "  parse errors    " + str( self.parse_errors ) + "\n"
+        string += "  sock errrors    " + str( self.socket_errors ) + "\n"
+        string += "  max pkts        " + str( self.max_pkts ) + "\n"
+        string += "  target switch   " + str( self.switch ) + "\n"
+        string += "  host            " + str( self.host ) + "\n"
+        string += "  port            " + str( self.port ) + "\n"
+        string += "  keep_alive      " + str( self.keep_alive ) + "\n"
+        string += "  pkt_in_run      " + str( self.pkt_in_run ) + "\n"
+        string += "  pkt_in_dropped  " + str( self.pkt_in_dropped ) + "\n"
+        return string
+
+    def show( self ):
+        print str( self )
+
+
+def sample_handler( controller, msg, pkt ):
+    """
+    Sample message handler
+
+    This is the prototype for functions registered with the controller
+    class for packet reception
+
+    @param controller The controller calling the handler
+    @param msg The parsed message object
+    @param pkt The raw packet that was received on the socket.  This is
+    in case the packet contains extra unparsed data.
+    @returns Boolean value indicating if the packet was handled.  If
+    not handled, the packet is placed in the queue for pollers to received
+    """
+    pass
diff --git a/Fabric/Utilities/src/python/oftest/dataplane.py b/Fabric/Utilities/src/python/oftest/dataplane.py
new file mode 100644
index 0000000..df79d47
--- /dev/null
+++ b/Fabric/Utilities/src/python/oftest/dataplane.py
@@ -0,0 +1,394 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+"""
+OpenFlow Test Framework
+
+DataPlane and DataPlanePort classes
+
+Provide the interface to the control the set of ports being used
+to stimulate the switch under test.
+
+See the class dataplaneport for more details.  This class wraps
+a set of those objects allowing general calls and parsing
+configuration.
+
+@todo Add "filters" for matching packets.  Actions supported
+for filters should include a callback or a counter
+"""
+
+import sys
+import os
+import socket
+import time
+import select
+import logging
+from threading import Thread
+from threading import Lock
+from threading import Condition
+import ofutils
+import netutils
+from pcap_writer import PcapWriter
+
+if "linux" in sys.platform:
+    import afpacket
+else:
+    import pcap
+
+def match_exp_pkt(self, exp_pkt, pkt):
+    """
+    Compare the string value of pkt with the string value of exp_pkt,
+    and return True iff they are identical.  If the length of exp_pkt is
+    less than the minimum Ethernet frame size (60 bytes), then padding
+    bytes in pkt are ignored.
+    """
+    e = str(exp_pkt)
+    p = str(pkt)
+    if len(e) < 60:
+        p = p[:len(e)]
+
+    #return e == p
+    #some nic card have capature problem, will have more bytes capatured.
+    if pkt.find(exp_pkt) >=0:
+        return True
+    else:
+        if self.config["dump_packet"]:
+            self.logger.debug("rx pkt    ->"+(" ".join("{:02x}".format(ord(c)) for c in pkt)))
+            self.logger.debug("expect pkt->"+(" ".join("{:02x}".format(ord(c)) for c in exp_pkt)))
+
+        return False
+
+
+class DataPlanePortLinux:
+    """
+    Uses raw sockets to capture and send packets on a network interface.
+    """
+
+    RCV_SIZE_DEFAULT = 4096
+    ETH_P_ALL = 0x03
+    RCV_TIMEOUT = 10000
+
+    def __init__(self, interface_name, port_number):
+        """
+        @param interface_name The name of the physical interface like eth1
+        """
+        self.interface_name = interface_name
+        self.socket = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, 0)
+        afpacket.enable_auxdata(self.socket)
+        self.socket.bind((interface_name, self.ETH_P_ALL))
+        netutils.set_promisc(self.socket, interface_name)
+        self.socket.settimeout(self.RCV_TIMEOUT)
+
+    def __del__(self):
+        if self.socket:
+            self.socket.close()
+
+    def fileno(self):
+        """
+        Return an integer file descriptor that can be passed to select(2).
+        """
+        return self.socket.fileno()
+
+    def recv(self):
+        """
+        Receive a packet from this port.
+        @retval (packet data, timestamp)
+        """
+        pkt = afpacket.recv(self.socket, self.RCV_SIZE_DEFAULT)
+        return (pkt, time.time())
+
+    def send(self, packet):
+        """
+        Send a packet out this port.
+        @param packet The packet data to send to the port
+        @retval The number of bytes sent
+        """
+        return self.socket.send(packet)
+
+    def down(self):
+        """
+        Bring the physical link down.
+        """
+        #os.system("ifconfig down %s" % self.interface_name)
+        os.system("ifconfig %s down" % self.interface_name)
+
+    def up(self):
+        """
+        Bring the physical link up.
+        """
+        #os.system("ifconfig up %s" % self.interface_name)
+        os.system("ifconfig %s up" % self.interface_name)
+
+
+class DataPlanePortPcap:
+    """
+    Alternate port implementation using libpcap. This is used by non-Linux
+    operating systems.
+    """
+
+    def __init__(self, interface_name, port_number):
+        self.pcap = pcap.pcap(interface_name)
+        self.pcap.setnonblock()
+
+    def fileno(self):
+        return self.pcap.fileno()
+
+    def recv(self):
+        (timestamp, pkt) = next(self.pcap)
+        return (pkt[:], timestamp)
+
+    def send(self, packet):
+        if hasattr(self.pcap, "inject"):
+            return self.pcap.inject(packet, len(packet))
+        else:
+           return self.pcap.sendpacket(packet)
+
+    def down(self):
+        pass
+
+    def up(self):
+        pass
+
+class DataPlane(Thread):
+    """
+    This class provides methods to send and receive packets on the dataplane.
+    It uses the DataPlanePort class, or an alternative implementation of that
+    interface, to do IO on a particular port. A background thread is used to
+    read packets from the dataplane ports and enqueue them to be read by the
+    test. The kill() method must be called to shutdown this thread.
+    """
+
+    MAX_QUEUE_LEN = 100
+
+    def __init__(self, config=None):
+        Thread.__init__(self)
+
+        # dict from port number to port object
+        self.ports = {}
+
+        # dict from port number to list of (timestamp, packet)
+        self.packet_queues = {}
+
+        # cvar serves double duty as a regular top level lock and
+        # as a condition variable
+        self.cvar = Condition()
+
+        # Used to wake up the event loop from another thread
+        self.waker = ofutils.EventDescriptor()
+        self.killed = False
+
+        self.logger = logging.getLogger("dataplane")
+        self.pcap_writer = None
+
+        if config is None:
+            self.config = {}
+        else:
+            self.config = config;
+
+        ############################################################
+        #
+        # The platform/config can provide a custom DataPlanePort class
+        # here if you have a custom implementation with different
+        # behavior.
+        #
+        # Set config.dataplane.portclass = MyDataPlanePortClass
+        # where MyDataPlanePortClass has the same interface as the class
+        # DataPlanePort defined here.
+        #
+        if "dataplane" in self.config and "portclass" in self.config["dataplane"]:
+            self.dppclass = self.config["dataplane"]["portclass"]
+        elif "linux" in sys.platform:
+            self.dppclass = DataPlanePortLinux
+        else:
+            self.dppclass = DataPlanePortPcap
+
+        self.start()
+
+    def run(self):
+        """
+        Activity function for class
+        """
+        while not self.killed:
+            sockets = [self.waker] + self.ports.values()
+            try:
+                sel_in, sel_out, sel_err = select.select(sockets, [], [], 1)
+            except:
+                print sys.exc_info()
+                self.logger.error("Select error, exiting")
+                break
+
+            with self.cvar:
+                for port in sel_in:
+                    if port == self.waker:
+                        self.waker.wait()
+                        continue
+                    else:
+                        # Enqueue packet
+                        pkt, timestamp = port.recv()
+                        port_number = port._port_number
+                        self.logger.debug("Pkt len %d in on port %d",
+                                          len(pkt), port_number)
+                        if self.pcap_writer:
+                            self.pcap_writer.write(pkt, timestamp, port_number)
+                        queue = self.packet_queues[port_number]
+                        if len(queue) >= self.MAX_QUEUE_LEN:
+                            # Queue full, throw away oldest
+                            queue.pop(0)
+                            self.logger.debug("Discarding oldest packet to make room")
+                        queue.append((pkt, timestamp))
+                self.cvar.notify_all()
+
+        self.logger.info("Thread exit")
+
+    def port_add(self, interface_name, port_number):
+        """
+        Add a port to the dataplane
+        @param interface_name The name of the physical interface like eth1
+        @param port_number The port number used to refer to the port
+        Stashes the port number on the created port object.
+        """
+        self.ports[port_number] = self.dppclass(interface_name, port_number)
+        self.ports[port_number]._port_number = port_number
+        self.packet_queues[port_number] = []
+        # Need to wake up event loop to change the sockets being selected on.
+        self.waker.notify()
+
+    def send(self, port_number, packet):
+        """
+        Send a packet to the given port
+        @param port_number The port to send the data to
+        @param packet Raw packet data to send to port
+        """
+        self.logger.debug("Sending %d bytes to port %d" %
+                          (len(packet), port_number))
+        if self.pcap_writer:
+            self.pcap_writer.write(packet, time.time(), port_number)
+        bytes = self.ports[port_number].send(packet)
+        if bytes != len(packet):
+            self.logger.error("Unhandled send error, length mismatch %d != %d" %
+                     (bytes, len(packet)))
+        return bytes
+
+    def oldest_port_number(self):
+        """
+        Returns the port number with the oldest packet, or
+        None if no packets are queued.
+        """
+        min_port_number = None
+        min_time = float('inf')
+        for (port_number, queue) in self.packet_queues.items():
+            if queue and queue[0][1] < min_time:
+                min_time = queue[0][1]
+                min_port_number = port_number
+        return min_port_number
+
+    # Dequeues and yields packets in the order they were received.
+    # Yields (port number, packet, received time).
+    # If port_number is not specified yields packets from all ports.
+    def packets(self, port_number=None):
+        while True:
+            rcv_port_number = port_number or self.oldest_port_number()
+
+            if rcv_port_number == None:
+                self.logger.debug("Out of packets on all ports")
+                break
+
+            queue = self.packet_queues[rcv_port_number]
+
+            if len(queue) == 0:
+                self.logger.debug("Out of packets on port %d", rcv_port_number)
+                break
+
+            pkt, time = queue.pop(0)
+            yield (rcv_port_number, pkt, time)
+
+    def poll(self, port_number=None, timeout=-1, exp_pkt=None):
+        """
+        Poll one or all dataplane ports for a packet
+
+        If port_number is given, get the oldest packet from that port.
+        Otherwise, find the port with the oldest packet and return
+        that packet.
+
+        If exp_pkt is true, discard all packets until that one is found
+
+        @param port_number If set, get packet from this port
+        @param timeout If positive and no packet is available, block
+        until a packet is received or for this many seconds
+        @param exp_pkt If not None, look for this packet and ignore any
+        others received.  Note that if port_number is None, all packets
+        from all ports will be discarded until the exp_pkt is found
+        @return The triple port_number, packet, pkt_time where packet
+        is received from port_number at time pkt_time.  If a timeout
+        occurs, return None, None, None
+        """
+
+        if exp_pkt and not port_number:
+            self.logger.warn("Dataplane poll with exp_pkt but no port number")
+
+        # Retrieve the packet. Returns (port number, packet, time).
+        def grab():
+            self.logger.debug("Grabbing packet")
+            for (rcv_port_number, pkt, time) in self.packets(port_number):
+                self.logger.debug("Checking packet from port %d", rcv_port_number)
+                if not exp_pkt or match_exp_pkt(self, exp_pkt, pkt):
+                    return (rcv_port_number, pkt, time)
+            self.logger.debug("Did not find packet")
+            return None
+
+        with self.cvar:
+            ret = ofutils.timed_wait(self.cvar, grab, timeout=timeout)
+
+        if ret != None:
+            return ret
+        else:
+            self.logger.debug("Poll time out, no packet from " + str(port_number))
+            return (None, None, None)
+
+    def kill(self):
+        """
+        Stop the dataplane thread.
+        """
+        self.killed = True
+        self.waker.notify()
+        self.join()
+        # Explicitly release ports to ensure we don't run out of sockets
+        # even if someone keeps holding a reference to the dataplane.
+        del self.ports
+
+    def port_down(self, port_number):
+        """Brings the specified port down"""
+        self.ports[port_number].down()
+
+    def port_up(self, port_number):
+        """Brings the specified port up"""
+        self.ports[port_number].up()
+
+    def flush(self):
+        """
+        Drop any queued packets.
+        """
+        for port_number in self.packet_queues.keys():
+            self.packet_queues[port_number] = []
+
+    def start_pcap(self, filename):
+        assert(self.pcap_writer == None)
+        self.pcap_writer = PcapWriter(filename)
+
+    def stop_pcap(self):
+        if self.pcap_writer:
+            self.pcap_writer.close()
+            self.pcap_writer = None
diff --git a/Fabric/Utilities/src/python/oftest/generators.py b/Fabric/Utilities/src/python/oftest/generators.py
new file mode 100644
index 0000000..74d2ccc
--- /dev/null
+++ b/Fabric/Utilities/src/python/oftest/generators.py
@@ -0,0 +1,95 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+from oftest.testutils import *
+from oftest import config
+import oftest.base_tests as base_tests
+import time
+
+class QinQPacketGenerator( base_tests.DataPlaneOnly ):
+    """
+    Generator for QinQ packets.
+    """
+    def runTest( self ):
+        # Get the ports and the interfaces
+        ports           = config[ "interfaces" ]
+        in_port         = ports[0][0]
+        in_interface    = ports[0][1].strip()
+        out_port        = ports[1][0]
+        out_interface   = ports[1][1].strip()
+        outer_vlan      = 20
+        innner_vlan     = 10
+        # Generating the packets
+        parsed_pkt = simple_tcp_packet_two_vlan(
+            pktlen=108,
+            out_dl_vlan_enable=True,
+            out_vlan_vid=outer_vlan,
+            in_dl_vlan_enable=True,
+            in_vlan_vid=innner_vlan
+            )
+        qinq_pkt = str( parsed_pkt )
+        # Sending the packet
+        print "\nSending packet on", out_interface
+        while True :
+            self.dataplane.send( in_port, qinq_pkt )
+            time.sleep(1)
+
+class VlanPacketGenerator( base_tests.DataPlaneOnly ):
+    """
+    Generator for vlan packets.
+    """
+    def runTest( self ):
+        # Get the ports and the interfaces
+        ports           = config[ "interfaces" ]
+        in_port         = ports[0][0]
+        in_interface    = ports[0][1].strip()
+        out_port        = ports[1][0]
+        out_interface   = ports[1][1].strip()
+        outer_vlan      = 20
+        # Generating the packets
+        parsed_pkt = simple_tcp_packet(
+            pktlen=108,
+            dl_vlan_enable=True,
+            vlan_vid=outer_vlan
+            )
+        vlan_pkt = str( parsed_pkt )
+        # Sending the packet
+        print "\nSending packet on", out_interface
+        while True :
+            self.dataplane.send( in_port, vlan_pkt )
+            time.sleep(1)
+
+class UntaggedPacketGenerator( base_tests.DataPlaneOnly ):
+    """
+    Generator for untagged packets.
+    """
+    def runTest( self ):
+        # Get the ports and the interfaces
+        ports           = config[ "interfaces" ]
+        in_port         = ports[0][0]
+        in_interface    = ports[0][1].strip()
+        out_port        = ports[1][0]
+        out_interface   = ports[1][1].strip()
+        # Generating the packets
+        parsed_pkt = simple_tcp_packet(
+            pktlen=108,
+            )
+        untagged_pkt = str( parsed_pkt )
+        # Sending the packet
+        print "\nSending packet on", out_interface
+        while True :
+            self.dataplane.send( in_port, untagged_pkt )
+            time.sleep(1)
diff --git a/Fabric/Utilities/src/python/oftest/help_formatter.py b/Fabric/Utilities/src/python/oftest/help_formatter.py
new file mode 100644
index 0000000..f877374
--- /dev/null
+++ b/Fabric/Utilities/src/python/oftest/help_formatter.py
@@ -0,0 +1,26 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+import optparse
+
+# Don't wrap description text to give us more control over newlines.
+class HelpFormatter(optparse.IndentedHelpFormatter):
+    def format_description(self, description):
+        if description:
+            indent = " "*self.current_indent
+            return indent + description
+        else:
+            return None
diff --git a/Fabric/Utilities/src/python/oftest/illegal_message.py b/Fabric/Utilities/src/python/oftest/illegal_message.py
new file mode 100644
index 0000000..94c9572
--- /dev/null
+++ b/Fabric/Utilities/src/python/oftest/illegal_message.py
@@ -0,0 +1,59 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+"""
+Support an illegal message
+"""
+
+import struct
+import ofp
+
+class illegal_message_type(object):
+    version = ofp.OFP_VERSION
+    type = 217
+
+    def __init__(self, xid=None):
+        self.xid = xid
+
+    def pack(self):
+        packed = []
+        packed.append(struct.pack("!B", self.version))
+        packed.append(struct.pack("!B", self.type))
+        packed.append(struct.pack("!H", 0)) # placeholder for length at index 2
+        packed.append(struct.pack("!L", self.xid))
+        length = sum([len(x) for x in packed])
+        packed[2] = struct.pack("!H", length)
+        return ''.join(packed)
+
+    @staticmethod
+    def unpack(buf):
+        raise NotImplementedError()
+
+    def __eq__(self, other):
+        if type(self) != type(other): return False
+        if self.version != other.version: return False
+        if self.type != other.type: return False
+        if self.xid != other.xid: return False
+        return True
+
+    def __ne__(self, other):
+        return not self.__eq__(other)
+
+    def __str__(self):
+        return self.show()
+
+    def show(self):
+        return "illegal_message_type"
diff --git a/Fabric/Utilities/src/python/oftest/mpls.py b/Fabric/Utilities/src/python/oftest/mpls.py
new file mode 100644
index 0000000..2754e87
--- /dev/null
+++ b/Fabric/Utilities/src/python/oftest/mpls.py
@@ -0,0 +1,40 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Imported from scapy at revision 1270:113ef25f9583
+# This file is not included in the Ubuntu packages of scapy, so it is checked
+# in to our repo to simplify installation. This file is under the GPLv2.
+
+# http://trac.secdev.org/scapy/ticket/31 
+
+# scapy.contrib.description = MPLS
+# scapy.contrib.status = loads
+
+from scapy.packet import Packet,bind_layers
+from scapy.fields import BitField,ByteField
+from scapy.layers.l2 import Ether
+
+class MPLS(Packet): 
+   name = "MPLS" 
+   fields_desc =  [ BitField("label", 3, 20), 
+                    BitField("cos", 0, 3), 
+                    BitField("s", 1, 1), 
+                    ByteField("ttl", 0)  ] 
+
+bind_layers(Ether, MPLS, type=0x8847)
+
+# Not in upstream scapy
+bind_layers(MPLS, MPLS, s=0)
diff --git a/Fabric/Utilities/src/python/oftest/netutils.py b/Fabric/Utilities/src/python/oftest/netutils.py
new file mode 100644
index 0000000..09a3835
--- /dev/null
+++ b/Fabric/Utilities/src/python/oftest/netutils.py
@@ -0,0 +1,77 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+
+"""
+Network utilities for the OpenFlow test framework
+"""
+
+###########################################################################
+##                                                                         ##
+## Promiscuous mode enable/disable                                         ##
+##                                                                         ##
+## Based on code from Scapy by Phillippe Biondi                            ##
+##                                                                         ##
+##                                                                         ##
+## This program is free software; you can redistribute it and/or modify it ##
+## under the terms of the GNU General Public License as published by the   ##
+## Free Software Foundation; either version 2, or (at your option) any     ##
+## later version.                                                          ##
+##                                                                         ##
+## This program is distributed in the hope that it will be useful, but     ##
+## WITHOUT ANY WARRANTY; without even the implied warranty of              ##
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU       ##
+## General Public License for more details.                                ##
+##                                                                         ##
+#############################################################################
+
+import socket
+from fcntl import ioctl
+import struct
+
+# From net/if_arp.h
+ARPHDR_ETHER = 1
+ARPHDR_LOOPBACK = 772
+
+# From bits/ioctls.h
+SIOCGIFHWADDR  = 0x8927          # Get hardware address
+SIOCGIFINDEX   = 0x8933          # name -> if_index mapping
+
+# From netpacket/packet.h
+PACKET_ADD_MEMBERSHIP  = 1
+PACKET_DROP_MEMBERSHIP = 2
+PACKET_MR_PROMISC      = 1
+
+# From bits/socket.h
+SOL_PACKET = 263
+
+def get_if(iff,cmd):
+  s=socket.socket()
+  ifreq = ioctl(s, cmd, struct.pack("16s16x",iff))
+  s.close()
+  return ifreq
+
+def get_if_index(iff):
+  return int(struct.unpack("I",get_if(iff, SIOCGIFINDEX)[16:20])[0])
+
+def set_promisc(s,iff,val=1):
+  mreq = struct.pack("IHH8s", get_if_index(iff), PACKET_MR_PROMISC, 0, "")
+  if val:
+      cmd = PACKET_ADD_MEMBERSHIP
+  else:
+      cmd = PACKET_DROP_MEMBERSHIP
+  s.setsockopt(SOL_PACKET, cmd, mreq)
+
diff --git a/Fabric/Utilities/src/python/oftest/ofdpa_utils.py b/Fabric/Utilities/src/python/oftest/ofdpa_utils.py
new file mode 100755
index 0000000..8c97b1f
--- /dev/null
+++ b/Fabric/Utilities/src/python/oftest/ofdpa_utils.py
@@ -0,0 +1,184 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+"""
+
+A set of inter-test utility functions for dealing with OF-DPA
+
+
+"""
+
+import logging, subprocess, time
+import ofp
+
+from oftest import config
+from oftest.testutils import *
+
+def forceOfdpaRestart( user ):
+    output = 1;
+    credential = user;
+    test = subprocess.Popen(["ssh", credential, "service ofdpa restart &> /dev/null"]);
+    time.sleep(1);
+    while output < 10:
+        output = int(subprocess.check_output(["ssh", credential, "client_cfg_purge | wc -l"]));
+        time.sleep(1);
+    subprocess.Popen(["ssh", credential, "brcm-indigo-ofdpa-ofagent -t 10.128.0.220 &> /dev/null"], stdout=subprocess.PIPE);
+
+def forceOfdpaStop( user ):
+    subprocess.Popen(["ssh", user, "ps ax | grep 'brcm-indigo-ofdpa-ofagent' | awk '{print $1}' | xargs sudo kill"], stdout=subprocess.PIPE);
+
+
+class table(object):
+    """ Metadata on each OFDPA table """
+    def __init__(self, table_id, table_name):
+        self.table_id = table_id
+        self.table_name = table_name
+    # TODO consider adding type checking verification here
+
+INGRESS_TABLE           = table(0, "Ingress")
+VLAN_TABLE              = table(10, "VLAN")
+MACTERM_TABLE           = table(20, "MacTerm")
+UNICAST_ROUTING_TABLE   = table(30, "Unicast Routing")
+MULTICAST_ROUTING_TABLE = table(40, "Multicast Routing")
+BRIDGING_TABLE          = table(50, "Bridging Table")
+ACL_TABLE               = table(60, "ACL Policy Table")
+#.... FIXME add all tables
+
+DEFAULT_VLAN = 1
+
+def enableVlanOnPort(controller, vlan, port=ofp.OFPP_ALL, priority=0):
+    if port == ofp.OFPP_ALL:
+        ports = sorted(config["port_map"].keys())
+    else:
+        ports = [port]
+    for port in ports:
+        tagged_match = ofp.match([
+                ofp.oxm.in_port(port),
+                ofp.oxm.vlan_vid(vlan | ofp.OFPVID_PRESENT)
+                ])
+
+        request = ofp.message.flow_add(
+            table_id = VLAN_TABLE.table_id,
+            cookie = 0xdead,
+            match = tagged_match,
+            instructions = [
+                ofp.instruction.goto_table(MACTERM_TABLE.table_id),
+#                 ofp.instruction.apply_actions(
+#                     actions=[
+#                         ofp.action.push_vlan(ethertype=0x8100), # DO NOT PUT THIS FOR OF-DPA 2.0 EA1 - seems to not matter for EA2
+#                         ofp.action.set_field(ofp.oxm.vlan_vid( ofp.OFPVID_PRESENT | vlan))
+#                     ]),
+                    ],
+            buffer_id = ofp.OFP_NO_BUFFER,
+            priority = priority)
+
+        logging.info("Inserting vlan rule allowing tagged vlan %d on port %d" % (vlan, port))
+        controller.message_send(request)
+        do_barrier(controller)
+        verify_no_errors(controller)
+
+
+def installDefaultVlan(controller, vlan=DEFAULT_VLAN, port=ofp.OFPP_ALL, priority=0):
+    """ Insert a rule that maps all untagged traffic to vlan $vlan
+
+    In OFDPA, table 10 (the vlan table) requires that all traffic be
+    mapped to an internal vlan else the packets be dropped.  This function
+    sets up a default vlan mapping all untagged traffic to an internal VLAN.
+
+    With OF-DPA, before you can insert a 'untagged to X' rule on a
+    port, you must first insert a 'X --> X' rule for the same port.
+
+    Further, the 'X --> X' rule must set ofp.OFPVID_PRESENT even
+    though 'X' is non-zero.
+
+    The 'controller' variable is self.controller from a test
+    """
+    # OFDPA seems to be dumb and wants each port set individually
+    #       Can't set all ports by using OFPP_ALL
+    if port == ofp.OFPP_ALL:
+        ports = sorted(config["port_map"].keys())
+    else:
+        ports = [port]
+
+    for port in ports:
+        # enable this vlan on this port before we can map untagged packets to the vlan
+        enableVlanOnPort(controller, vlan, port)
+
+        untagged_match = ofp.match([
+                ofp.oxm.in_port(port),
+                # OFDPA 2.0 says untagged is vlan_id=0, mask=ofp.OFPVID_PRESENT
+                ofp.oxm.vlan_vid_masked(0,ofp.OFPVID_PRESENT)    # WTF OFDPA 2.0EA2 -- really!?
+                ])
+
+        request = ofp.message.flow_add(
+            table_id = VLAN_TABLE.table_id,
+            cookie = 0xbeef,
+            match = untagged_match,
+            instructions = [
+                ofp.instruction.apply_actions(
+                    actions=[
+                        #ofp.action.push_vlan(ethertype=0x8100),
+                        ofp.action.set_field(ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT | vlan))
+                    ]),
+                ofp.instruction.goto_table(MACTERM_TABLE.table_id)   
+                    ],
+            buffer_id = ofp.OFP_NO_BUFFER,
+            priority = priority)
+
+        logging.info("Inserting default vlan sending all untagged traffic to vlan %d on port %d" % (vlan, port))
+        controller.message_send(request)
+        do_barrier(controller)
+        verify_no_errors(controller)
+
+
+_group_types = {
+    "L2 Interface": 0,
+    "L2 Rewrite" : 1,
+    "L3 Unicast" : 2,
+    "L2 Multicast" : 3,
+    "L2 Flood" : 4,
+    "L3 Interface" : 5,
+    "L3 Multicast": 6,
+    "L3 ECMP": 7,
+    "L2 Data Center Overlay": 8,
+    "MPLS Label" : 9,
+    "MPLS Forwarding" :10,
+    "L2 Unfiltered Interface": 11,
+    "L2 Loopback": 12,
+}
+
+
+def makeGroupID(groupType, local_id):
+    """ Group IDs in OF-DPA have rich meaning
+
+    @param groupType is a key in _group_types
+    @param local_id is an integer 0<= local_id < 2**27,
+        but it may have more semantic meaning depending on the
+        groupType
+
+
+    Read Section 4.3 of the OF-DPA manual on groups for 
+    details
+    """
+    if groupType not in _group_types:
+        raise KeyError("%s not a valid OF-DPA group type" % groupType)
+    if local_id < 0 or local_id >=134217728:
+        raise ValueError("local_id %d must be  0<= local_id < 2**27" % local_id)
+    return (_group_types[groupType] << 28) + local_id
+
+
+def delete_all_recursive_groups(controller):
+    pass
diff --git a/Fabric/Utilities/src/python/oftest/oft12/__init__.py b/Fabric/Utilities/src/python/oftest/oft12/__init__.py
new file mode 100644
index 0000000..d4e8062
--- /dev/null
+++ b/Fabric/Utilities/src/python/oftest/oft12/__init__.py
@@ -0,0 +1,16 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
diff --git a/Fabric/Utilities/src/python/oftest/oft12/packet.py b/Fabric/Utilities/src/python/oftest/oft12/packet.py
new file mode 100644
index 0000000..55724d6
--- /dev/null
+++ b/Fabric/Utilities/src/python/oftest/oft12/packet.py
@@ -0,0 +1,1315 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+######################################################################
+#
+# All files associated with the OpenFlow Python Test (oftest) are
+# made available for public use and benefit with the expectation
+# that others will use, modify and enhance the Software and contribute
+# those enhancements back to the community. However, since we would
+# like to make the Software available for broadest use, with as few
+# restrictions as possible permission is hereby granted, free of
+# charge, to any person obtaining a copy of this Software to deal in
+# the Software under the copyrights without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject
+# to the following conditions:
+# 
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# 
+######################################################################
+import os
+
+"""
+OpenFlow packet class
+
+This class implements the basic abstraction of an OpenFlow packet.  It
+includes parsing functionality and OpenFlow actions related to 
+packet modifications.
+"""
+
+import socket
+import struct
+import logging
+import ofp
+import unittest
+import binascii
+import string
+import collections #@UnresolvedImport
+
+ETHERTYPE_IP = 0x0800
+ETHERTYPE_VLAN = 0x8100
+ETHERTYPE_VLAN_QinQ = 0x88a8
+ETHERTYPE_ARP = 0x0806
+ETHERTYPE_MPLS = 0x8847
+ETHERTYPE_MPLS_MCAST = 0x8848
+ETHERTYPES_MPLS = [ETHERTYPE_MPLS, ETHERTYPE_MPLS_MCAST]
+
+DL_MASK_ALL = [0xff, 0xff, 0xff, 0xff, 0xff, 0xff]
+NW_MASK_ALL = 0xffffffff
+
+MPLS_BOTTOM_OF_STACK = 0x00000100
+
+# Sigh.. not python26
+#MplsTag = collections.namedtuple("MplsTag", "label tc ttl")
+
+class MplsTag(object):
+    def __init__(self, label, tc, ttl):
+        self.label = label
+        self.tc = tc
+        self.ttl = ttl
+    def pack(self, bos = 0):
+        packed_tag = ((self.label & 0xfffff) << 12) | \
+                     ((self.tc & 0x7) << 9) | \
+                     (self.ttl & 0xFF) | \
+                     (MPLS_BOTTOM_OF_STACK if bos else 0)
+        return packed_tag
+    
+    def unpack(packed_tag):
+        tag = MplsTag(packed_tag >> 12,
+                      (packed_tag >> 9) & 0x0007,
+                      packed_tag & 0xFF)
+        bos = bool(packed_tag & MPLS_BOTTOM_OF_STACK)
+        return (tag, bos)
+    unpack = staticmethod(unpack)
+
+class Packet(object):
+    """
+    Packet abstraction
+
+    This is meant to support the abstraction of a packet in an
+    OpenFlow 1.1 switch so it includes an action set, ingress port,
+    and metadata.  These members may be ignored and the rest of the
+    packet parsing and modification functions used to manipulate
+    a packet.
+    """
+    
+    icmp_counter = 1
+
+    def __init__(self, in_port=None, data=""):
+        # Use entries in match when possible.
+        self.in_port = in_port
+        self.data = data
+        self.bytes = len(data)
+        self.match = ofp.ofp_match()
+        self.logger = logging.getLogger("packet")  
+        self.instructions = []
+        # parsable tags
+        self.ip_header_offset = None
+        self.tcp_header_offset = None
+        self.mpls_tag_offset = None         # pointer to outer mpls tag
+        self.vlan_tag_offset = None         # pointer to outer vlan tag
+        self.action_set = {}
+        self.queue_id = 0
+
+        if self.data != "":
+            self.parse()
+
+    def show(self):
+        """ Return a ascii hex representation of the packet's data"""
+        ret = ""
+        c = 0
+        for b in list(self.data):
+            if c != 0:
+                if c % 16  == 0:
+                    ret += '\n'
+                elif c % 8 == 0:
+                    ret += '  '
+            c += 1
+            ret += "%0.2x " % struct.unpack('B', b)
+        return ret
+
+    def __repr__(self):
+        return self.data
+    
+    def __str__(self):
+        return  self.__repr__()
+
+    def __len__(self):
+        return len(self.data)
+
+    def simple_tcp_packet(self,
+                          pktlen=100, 
+                          dl_dst='00:01:02:03:04:05',
+                          dl_src='00:06:07:08:09:0a',
+                          dl_vlan_enable=False,
+                          dl_vlan_type=ETHERTYPE_VLAN,
+                          dl_vlan=0,
+                          dl_vlan_pcp=0,
+                          dl_vlan_cfi=0,
+                          mpls_type=None,
+                          mpls_tags=None,
+                          ip_src='192.168.0.1',
+                          ip_dst='192.168.0.2',
+                          ip_tos=0,
+                          ip_ttl=64,
+                          tcp_sport=1234,
+                          tcp_dport=80):
+        """
+        Return a simple dataplane TCP packet
+
+        Supports a few parameters:
+        @param len Length of packet in bytes w/o CRC
+        @param dl_dst Destinatino MAC
+        @param dl_src Source MAC
+        @param dl_vlan_enable True if the packet is with vlan, False otherwise
+        @param dl_vlan_type Ether type for VLAN
+        @param dl_vlan VLAN ID
+        @param dl_vlan_pcp VLAN priority
+        @param ip_src IP source
+        @param ip_dst IP destination
+        @param ip_tos IP ToS
+        @param tcp_dport TCP destination port
+        @param tcp_sport TCP source port
+
+        Generates a simple TCP request.  Users shouldn't assume anything 
+        about this packet other than that it is a valid ethernet/IP/TCP frame.
+        """
+        self.data = ""
+        self._make_ip_packet(dl_dst, dl_src, dl_vlan_enable, dl_vlan_type, 
+                             dl_vlan, dl_vlan_pcp, dl_vlan_cfi, 
+                             mpls_type, mpls_tags, 
+                             ip_tos, ip_ttl, ip_src, ip_dst, socket.IPPROTO_TCP)
+
+        # Add TCP header
+        self.data += struct.pack("!HHLLBBHHH",
+                                 tcp_sport,
+                                 tcp_dport,
+                                 1,     # tcp.seq
+                                 0,     # tcp.ack
+                                 0x50,  # tcp.doff + tcp.res1
+                                 0x12,  # tcp.syn + tcp.ack
+                                 0,     # tcp.wnd
+                                 0,     # tcp.check
+                                 0,     # tcp.urgent pointer
+                                 )
+
+        # Fill out packet
+        self.data += "D" * (pktlen - len(self.data))
+        return self
+    
+    def simple_icmp_packet(self,
+                          pktlen=100, 
+                          dl_dst='00:01:02:03:04:05',
+                          dl_src='00:06:07:08:09:0a',
+                          dl_vlan_enable=False,
+                          dl_vlan_type=ETHERTYPE_VLAN,
+                          dl_vlan=0,
+                          dl_vlan_pcp=0,
+                          dl_vlan_cfi=0,
+                          mpls_type=None,
+                          mpls_tags=None,
+                          ip_src='192.168.0.1',
+                          ip_dst='192.168.0.2',
+                          ip_tos=0,
+                          ip_ttl=64,
+                          icmp_type=8, # ICMP_ECHO_REQUEST
+                          icmp_code=0, 
+                          ):
+        """
+        Return a simple dataplane ICMP packet
+
+        Supports a few parameters:
+        @param len Length of packet in bytes w/o CRC
+        @param dl_dst Destinatino MAC
+        @param dl_src Source MAC
+        @param dl_vlan_enable True if the packet is with vlan, False otherwise
+        @param dl_vlan_type Ether type for VLAN
+        @param dl_vlan VLAN ID
+        @param dl_vlan_pcp VLAN priority
+        @param ip_src IP source
+        @param ip_dst IP destination
+        @param ip_tos IP ToS
+        @param tcp_dport TCP destination port
+        @param ip_sport TCP source port
+
+        Generates a simple TCP request.  Users shouldn't assume anything 
+        about this packet other than that it is a valid ethernet/IP/TCP frame.
+        """
+        self.data = ""
+        self._make_ip_packet(dl_dst, dl_src, dl_vlan_enable, dl_vlan_type, 
+                             dl_vlan, dl_vlan_pcp, dl_vlan_cfi, 
+                             mpls_type, mpls_tags,
+                             ip_tos,
+                              ip_ttl, ip_src, ip_dst, socket.IPPROTO_ICMP)
+
+        # Add ICMP header
+        self.data += struct.pack("!BBHHH",
+                                 icmp_type,
+                                 icmp_code,
+                                 0,  # icmp.checksum
+                                 os.getpid() & 0xffff,  # icmp.echo.id
+                                 Packet.icmp_counter   # icmp.echo.seq
+                                 )                  
+        Packet.icmp_counter += 1       
+
+        # Fill out packet
+        self.data += "D" * (pktlen - len(self.data))
+
+        return self
+
+    def _make_ip_packet(self, dl_dst, dl_src, dl_vlan_enable, dl_vlan_type, 
+                          dl_vlan, dl_vlan_pcp, dl_vlan_cfi, mpls_type, mpls_tags,
+                          ip_tos, ip_ttl, ip_src, ip_dst, ip_proto):
+        self.data = ""
+        addr = dl_dst.split(":")
+        for byte in map(lambda z: int(z, 16), addr):
+            self.data += struct.pack("!B", byte)
+        addr = dl_src.split(":")
+        for byte in map(lambda z: int(z, 16), addr):
+            self.data += struct.pack("!B", byte)
+
+        if (dl_vlan_enable):
+            # Form and add VLAN tag
+            self.data += struct.pack("!H", dl_vlan_type)
+            vtag = (dl_vlan & 0x0fff) | \
+                            (dl_vlan_pcp & 0x7) << 13 | \
+                            (dl_vlan_cfi & 0x1) << 12
+            self.data += struct.pack("!H", vtag)
+            
+        if mpls_tags:
+            # Add type/len field
+            self.data += struct.pack("!H", mpls_type)
+            mpls_tags = list(mpls_tags)          
+            while len(mpls_tags):
+                tag = mpls_tags.pop(0)
+                packed_tag = tag.pack(bos = not len(mpls_tags))
+                self.data += struct.pack("!I", packed_tag)
+            
+        else:
+            # Add type/len field
+            self.data += struct.pack("!H", ETHERTYPE_IP)
+
+        # Add IP header
+        v_and_hlen = 0x45  # assumes no ip or tcp options
+        ip_len = 120 + 40  # assumes no ip or tcp options
+        self.data += struct.pack("!BBHHHBBH", v_and_hlen, ip_tos, ip_len, 
+                                 0, # ip.id 
+                                 0, # ip.frag_off
+                                 ip_ttl, # ip.ttl
+                                 ip_proto,
+                                 0)  # ip.checksum
+        # convert  ipsrc/dst to ints
+        self.data += struct.pack("!LL", ascii_ip_to_bin(ip_src), 
+                                 ascii_ip_to_bin(ip_dst))
+
+    def length(self):
+        return len(self.data)
+
+    def clear_actions(self):
+        self.action_set = {}
+
+    def parse(self):
+        """
+        Update the headers in self.match based on self.data 
+        
+        Parses the relevant header features out of the packet, using
+        the table outlined in the OF1.1 spec, Figure 4
+        """
+        self.bytes = len(self.data)
+        self.match.in_port = self.in_port
+        self.match.type = ofp.OFPMT_STANDARD
+        self.match.length = ofp.OFPMT_STANDARD_LENGTH
+        self.match.wildcards = 0
+        self.match.nw_dst_mask = 0
+        self.match.nw_dst_mask = 0
+        self.match.dl_dst_mask = [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
+        self.match.dl_src_mask = [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
+        self.mpls_tag_offset = None
+        self.ip_header_offset = None
+        
+        idx = 0
+        try:
+            idx = self._parse_l2(idx)
+            
+            if self.match.dl_type == ETHERTYPE_IP:
+                self.ip_header_offset = idx 
+                idx = self._parse_ip(idx)
+                if self.match.nw_proto in [ socket.IPPROTO_TCP,
+                                            socket.IPPROTO_UDP,
+                                            socket.IPPROTO_ICMP]:
+                    self.tcp_header_offset = idx
+                    if self.match.nw_proto != socket.IPPROTO_ICMP:
+                        idx = self._parse_l4(idx)
+                    else:
+                        idx = self._parse_icmp(idx)
+            elif self.match.dl_type == ETHERTYPE_ARP:
+                self._parse_arp(idx)
+        except (parse_error), e:
+            self.logger.warn("Giving up on parsing packet, got %s" % 
+                             (str(e)))
+            return None
+        return self.match
+
+    def _parse_arp(self, idx):
+        # @todo Implement
+        pass
+
+    def _parse_l2(self, idx):
+        """
+        Parse Layer2 Headers of packet
+        
+        Parse ether src,dst,type (and vlan and QinQ headers if exists) from 
+        self.data starting at idx
+        """
+        if self.bytes < 14 :
+            raise parse_error("_parse_l2:: packet too shorter <14 bytes")
+            
+        self.match.dl_dst = list(struct.unpack("!6B", self.data[idx:idx+6]))
+        self.match.dl_dst_mask = DL_MASK_ALL
+        idx += 6
+        self.match.dl_src = list(struct.unpack("!6B", self.data[idx:idx+6]))
+        self.match.dl_src_mask = DL_MASK_ALL
+        idx += 6
+        #pdb.set_trace()
+        l2_type = struct.unpack("!H", self.data[idx:idx+2])[0]
+        idx += 2
+        if l2_type in [ETHERTYPE_VLAN, ETHERTYPE_VLAN_QinQ] :
+            self.vlan_tag_offset = 12
+            blob = struct.unpack("!H", self.data[idx:idx+2])[0]
+            idx += 2
+            self.match.dl_vlan_pcp = (blob & 0xe000) >> 13
+            #cfi = blob & 0x1000     #@todo figure out what to do if cfi!=0
+            self.match.dl_vlan = blob & 0x0fff
+            l2_type = struct.unpack("!H", self.data[idx:idx+2])[0]
+            # now skip past any more nest VLAN tags (per the spec)
+            while l2_type in [ETHERTYPE_VLAN, ETHERTYPE_VLAN_QinQ] :
+                idx += 4
+                if self.bytes < idx :
+                    raise parse_error("_parse_l2(): Too many vlan tags")
+                l2_type = struct.unpack("!H", self.data[idx:idx+2])[0]
+            idx += 2
+        else:
+            self.vlan_tag_offset = None
+            self.match.dl_vlan = ofp.OFPVID_NONE
+            self.match.dl_vlan_pcp = 0
+            
+        if l2_type in ETHERTYPES_MPLS:
+            if self.bytes < (idx + 4):
+                raise parse_error("_parse_l2:  Invalid MPLS header")
+            self.mpls_tag_offset = idx
+            tag = struct.unpack("!I", self.data[idx:idx+4])[0]
+            self.match.mpls_label = tag >> 12
+            self.match.mpls_tc = (tag >> 9) & 0x0007
+            idx += 4
+        else:
+            self.match.mpls_label = 0
+            self.match.mpls_tc = 0
+            
+        self.match.dl_type = l2_type
+        return idx
+            
+    def _parse_ip(self, idx):
+        """
+        Parse IP Headers of a packet starting at self.data[idx]
+        """
+        if self.bytes < (idx + 20) :
+            raise parse_error("_parse_ip: Invalid IP header")
+        # the three blanks are id (2bytes), frag offset (2bytes), 
+        # and ttl (1byte)
+        (hlen_and_v, self.match.nw_tos, len, _,_,_, self.match.nw_proto) = \
+            struct.unpack("!BBHHHBB", self.data[idx:idx+10])
+        #@todo add fragmentation parsing
+        hlen = hlen_and_v & 0x0f
+        (self.match.nw_src, self.match.nw_dst) = \
+            struct.unpack("!II", self.data[idx + 12:idx+20])
+        self.match.nw_dst_mask = NW_MASK_ALL
+        self.match.nw_src_mask = NW_MASK_ALL
+        return idx + (hlen *4) # this should correctly skip IP options
+    
+    def _parse_l4(self, idx):
+        """
+        Parse the src/dst ports of UDP and TCP packets
+        """
+        if self.bytes < (idx + 8):
+            raise parse_error("_parse_l4: Invalid L4 header")
+        (self.match.tp_src, self.match.tp_dst) = \
+            struct.unpack("!HH", self.data[idx:idx+4])
+
+    def _parse_icmp(self, idx):
+        """
+        Parse the type/code of ICMP Packets 
+        """
+        if self.bytes < (idx + 4):
+            raise parse_error("_parse_icmp: Invalid icmp header")
+        # yes, type and code get stored into tp_dst and tp_src...
+        (self.match.tp_src, self.match.tp_dst) = \
+            struct.unpack("!BB", self.data[idx:idx+2])
+
+
+    #
+    # NOTE:  See comment string in write_action regarding exactly
+    # when actions are executed (for apply vs write instructions)
+    #
+
+    def write_action(self, action):
+        """
+        Write the action into the packet's action set
+
+        Note that we do nothing to the packet when the write_action
+        instruction is executed.  We only record the actions for 
+        later processing.  Because of this, the output port is not
+        explicitly recorded in the packet; that state is recorded
+        in the action_set[set_output] item.
+        """
+        self.action_set[action.__class__] = action
+
+    def _set_1bytes(self,offset,byte):
+        """ Writes the byte at data[offset] 
+        
+        This function only exists to match the other _set_Xbytes() and
+        is trivial
+    
+        """
+        tmp= "%s%s" % (self.data[0:offset], 
+                               struct.pack('B',byte & 0xff))
+        if len(self.data) > offset + 1 :
+            tmp += self.data[offset+1:len(self.data)]
+        self.data=tmp
+
+    def _set_2bytes(self,offset,short):
+        """ Writes the 2 byte short in network byte order at data[offset] """
+        tmp= "%s%s" % (self.data[0:offset], 
+                               struct.pack('!H',short & 0xffff))
+        if len(self.data) > offset + 2 :
+            tmp += self.data[offset+2:len(self.data)]
+        self.data=tmp
+
+    def _set_4bytes(self,offset,word,forceNBO=True):
+        """ Writes the 4 byte word at data[offset] 
+        
+        Use network byte order if forceNBO is True,
+        else it's assumed that word is already in NBO
+        
+        """
+        # @todo Verify byte order
+        #pdb.set_trace()
+        fmt ="L"
+        if forceNBO:
+            fmt = '!' + fmt 
+        
+        tmp= "%s%s" % (self.data[0:offset], 
+                               struct.pack(fmt,word & 0xffffffff))
+        if len(self.data) > offset + 4 :
+            tmp += self.data[offset+4:len(self.data)]
+        self.data=tmp
+        
+    def _set_6bytes(self,offset,byte_list):
+        """ Writes the 6 byte sequence in the given order to data[offset] """
+        # @todo Do as a slice
+        tmp= self.data[0:offset] 
+        tmp += struct.pack("BBBBBB", *byte_list)
+        if len(self.data) > offset + 6 :
+            tmp += self.data[offset+6:len(self.data)]
+        self.data=tmp
+    
+    def _update_l4_checksum(self):
+        """ Recalculate the L4 checksum, if there
+        
+        Can be safely called on non-tcp/non-udp packets as a NOOP
+        """
+        if (self.ip_header_offset is None or 
+            self.tcp_header_offset is None):
+            return
+        if self.match.nw_proto == socket.IPPROTO_TCP:
+            return self._update_tcp_checksum()
+        elif self.match.nw_proto == socket.IPPROTO_UDP:
+            return self._update_udp_checksum()
+        
+    def _update_tcp_checksum(self):
+        """ Recalculate the TCP checksum
+        
+        @warning:  Must only be called on actual TCP Packets
+        """
+        #@todo implemnt tcp checksum update
+        pass
+    
+    def _update_udp_checksum(self):
+        """ Recalculate the TCP checksum
+        
+        @warning:  Must only be called on actual TCP Packets
+        """
+        #@todo implemnt udp checksum update
+        pass
+
+    def set_metadata(self, value, mask):
+        self.match.metadata = (self.match.metadata & ~mask) | \
+            (value & mask)
+
+    #
+    # These are the main action operations that take the 
+    # required parameters
+    # 
+    # Note that 'group', 'experimenter' and 'set_output' are only 
+    # implemented for the action versions.
+
+    def set_queue(self, queue_id):
+        self.queue_id = queue_id
+
+    def set_vlan_vid(self, vid):
+        # @todo Verify proper location of VLAN id
+        if self.vlan_tag_offset is None:
+            self.logger.debug("set_vlan_vid(): Adding new vlan tag to untagged packet")
+            self.push_vlan(ETHERTYPE_VLAN)
+        offset = self.vlan_tag_offset + 2
+        short = struct.unpack('!H', self.data[offset:offset+2])[0]
+        short = (short & 0xf000) | ((vid & 0x0fff) )
+        self.data = self.data[0:offset] + struct.pack('!H',short) + \
+                self.data[offset+2:len(self.data)]
+        self.match.dl_vlan = vid & 0x0fff
+        self.logger.debug("set_vlan_vid(): setting packet vlan_vid to 0x%x " % 
+                          self.match.dl_vlan)
+
+    def set_vlan_pcp(self, pcp):
+        # @todo Verify proper location of VLAN pcp
+        if self.vlan_tag_offset is None:
+            return
+        offset = self.vlan_tag_offset + 2
+        short = struct.unpack('!H', self.data[offset:offset+2])[0]
+        short = (pcp<<13 & 0xf000) | ((short & 0x0fff) )
+        self.data = self.data[0:offset] + struct.pack('!H',short) + \
+                self.data[offset+2:len(self.data)]
+        self.match.dl_vlan_pcp = pcp & 0xf
+
+    def set_dl_src(self, dl_src):
+        self._set_6bytes(6, dl_src)
+        self.match.dl_src = dl_src
+
+    def set_dl_dst(self, dl_dst):
+        self._set_6bytes(0, dl_dst)
+        self.match.dl_dst = dl_dst
+        
+    def set_nw_src(self, nw_src):
+        if self.ip_header_offset is None:
+            return
+        self._set_4bytes(self.ip_header_offset + 12, nw_src)
+        self._update_l4_checksum()
+        self.match.nw_src = nw_src
+    
+    def set_nw_dst(self, nw_dst):
+        # @todo Verify byte order
+        if self.ip_header_offset is None:
+            return
+        self._set_4bytes(self.ip_header_offset + 16, nw_dst)
+        self._update_l4_checksum()
+        self.match.nw_dst = nw_dst
+
+    def set_nw_tos(self, tos):
+        if self.ip_header_offset is None:
+            return
+        self._set_1bytes(self.ip_header_offset + 1, tos)
+        self.match.nw_tos = tos
+
+    def set_nw_ecn(self, ecn):
+        #@todo look up ecn implementation details
+        pass
+
+    def set_tp_src(self, tp_src):
+        if self.tcp_header_offset is None:
+            return
+        if (self.match.nw_proto == socket.IPPROTO_TCP or
+            self.match.nw_proto == socket.IPPROTO_UDP): 
+            self._set_2bytes(self.tcp_header_offset, tp_src)
+        elif (self.match.nw_proto == socket.IPPROTO_ICMP):
+            self._set_1bytes(self.tcp_header_offset, tp_src)
+        self._update_l4_checksum()
+        self.match.tp_src = tp_src
+            
+    def set_tp_dst(self, tp_dst):
+        if self.tcp_header_offset is None:
+            return
+        if (self.match.nw_proto == socket.IPPROTO_TCP or
+            self.match.nw_proto == socket.IPPROTO_UDP): 
+            self._set_2bytes(self.tcp_header_offset +2, tp_dst)
+        elif (self.match.nw_proto == socket.IPPROTO_ICMP):
+            self._set_1bytes(self.tcp_header_offset + 1, tp_dst)
+        self._update_l4_checksum()
+        self.match.tp_dst = tp_dst
+
+    IP_OFFSET_TTL = 8
+    
+    def copy_ttl_out(self):
+        if self.mpls_tag_offset is None:
+            # No MPLS tag.
+            return
+        outerTag = struct.unpack("!I", self.data[self.mpls_tag_offset:
+                                                 self.mpls_tag_offset+4])[0]
+        if not (outerTag & MPLS_BOTTOM_OF_STACK):
+            # Payload is another MPLS tag:
+            innerTag = struct.unpack("!I", self.data[self.mpls_tag_offset+4:
+                                                     self.mpls_tag_offset+8])[0]
+            outerTag = (outerTag & 0xFFFFFF00) | (innerTag & 0x000000FF)
+            self._set_4bytes(self.mpls_tag_offset, outerTag)
+        else:
+            # This MPLS tag is the bottom of the stack.
+            # See if the payload looks like it might be IPv4.
+            versionLen = struct.unpack("B", 
+                                       self.data[self.mpls_tag_offset+4])[0]
+            if versionLen >> 4 != 4:
+                # This is not IPv4.
+                return;
+            # This looks like IPv4, so copy the TTL.
+            ipTTL = struct.unpack("B", self.data[self.mpls_tag_offset + 4 +
+                                                 Packet.IP_OFFSET_TTL])[0]
+            outerTag = (outerTag & 0xFFFFFF00) | (ipTTL & 0xFF)
+            self._set_4bytes(self.mpls_tag_offset, outerTag)      
+            return
+
+    def copy_ttl_in(self):
+        if self.mpls_tag_offset is None:
+            # No MPLS tag.
+            return
+        outerTag = struct.unpack("!I", self.data[self.mpls_tag_offset:
+                                                 self.mpls_tag_offset+4])[0]
+        if not (outerTag & MPLS_BOTTOM_OF_STACK):
+            # Payload is another MPLS tag:
+            innerTag = struct.unpack("!I", self.data[self.mpls_tag_offset+4:
+                                                     self.mpls_tag_offset+8])[0]
+            innerTag = (innerTag & 0xFFFFFF00) | (outerTag & 0x000000FF)
+            self._set_4bytes(self.mpls_tag_offset+4, innerTag)
+        else:
+            # This MPLS tag is the bottom of the stack.
+            # See if the payload looks like it might be IPv4.
+            versionLen = struct.unpack("B", self.data[self.mpls_tag_offset+4])[0]
+            if versionLen >> 4 != 4:
+                # This is not IPv4.
+                return;
+            # This looks like IPv4, so copy the TTL.
+            self._set_1bytes(self.mpls_tag_offset + 4 + Packet.IP_OFFSET_TTL,
+                             outerTag & 0x000000FF) 
+            #@todo update checksum
+            return
+
+    def set_mpls_label(self, mpls_label):
+        if self.mpls_tag_offset is None:
+            return
+        tag = struct.unpack("!I", self.data[self.mpls_tag_offset:
+                                            self.mpls_tag_offset+4])[0]
+        tag = ((mpls_label & 0xfffff) << 12) | (tag & 0x00000fff)
+        self.match.mpls_label = mpls_label
+        self._set_4bytes(self.mpls_tag_offset, tag)
+
+    def set_mpls_tc(self, mpls_tc):
+        if self.mpls_tag_offset is None:
+            return
+        tag = struct.unpack("!I", self.data[self.mpls_tag_offset:
+                                            self.mpls_tag_offset+4])[0]
+        tag = ((mpls_tc & 0x7) << 9) | (tag & 0xfffff1ff)
+        self.match.mpls_tc = mpls_tc
+        self._set_4bytes(self.mpls_tag_offset, tag)
+
+    def set_mpls_ttl(self, ttl):
+        if self.mpls_tag_offset is None:
+            return   
+        self._set_1bytes(self.mpls_tag_offset + 3, ttl)
+
+    def dec_mpls_ttl(self):
+        if self.mpls_tag_offset is None:
+            return
+        ttl = struct.unpack("B", self.data[self.mpls_tag_offset + 3])[0]
+        self.set_mpls_ttl(ttl - 1)
+
+    def push_vlan(self, ethertype):
+        if len(self) < 14: 
+            self.logger.error("NOT Pushing a new VLAN tag: packet too short!")
+            pass    # invalid ethernet frame, can't add vlan tag
+
+        # from 4.8.1 of the spec, default values are zero
+        # on a push operation if no VLAN tag already exists
+        l2_type = struct.unpack("!H", self.data[12:14])[0]
+        if ((l2_type == ETHERTYPE_VLAN) or (l2_type == ETHERTYPE_VLAN_QinQ)):
+            current_tag = struct.unpack("!H", self.data[14:16])[0]
+        else:
+            current_tag = 0
+        new_tag = struct.pack('!HH',
+                                  # one of 0x8100 or x88a8
+                                  # could check to enforce this?
+                                  ethertype & 0xffff,
+                                  current_tag
+                                  )
+        self.data = self.data[0:12] + new_tag + self.data[12:len(self.data)]  
+        self.parse()
+
+    def pop_vlan(self):
+        if self.vlan_tag_offset is None:
+            pass
+        self.data = self.data[0:12] + self.data[16:len(self.data)]
+        self.parse()
+
+    def push_mpls(self, ethertype):
+        tag = MplsTag(0, 0, 0)
+        bos = False
+        
+        if self.mpls_tag_offset:
+            # The new tag defaults to the old one.
+            packed_tag = struct.unpack("!I", self.data[self.mpls_tag_offset:
+                                                       self.mpls_tag_offset+4])[0]
+            (tag, _) = MplsTag.unpack(packed_tag)
+            
+        else:
+            # Pushing a new label stack, set the BoS bit and get TTL from IP.
+            bos = True
+            if self.ip_header_offset:
+                ttl = struct.unpack("B", self.data[self.ip_header_offset + \
+                                                       Packet.IP_OFFSET_TTL])[0]
+                tag = MplsTag(0, 0, ttl)
+                                                       
+        self.data = self.data[0:14] + \
+                    struct.pack("!I", tag.pack(bos)) + \
+                    self.data[14:]
+        self._set_2bytes(12, ethertype)   
+        # Reparse to update offsets, ethertype, etc.
+        self.parse()
+            
+    def pop_mpls(self, ethertype):
+        # Ignore if no existing tags.
+        if self.mpls_tag_offset:
+            self.data = self.data[0:self.mpls_tag_offset] + \
+                        self.data[self.mpls_tag_offset + 4:]
+            self._set_2bytes(12, ethertype)
+            
+            # Reparse to update offsets, ethertype, etc.
+            self.parse()
+    
+    def set_nw_ttl(self, ttl):
+        if self.ip_header_offset is None:
+            return
+        self._set_1bytes(self.ip_header_offset + Packet.IP_OFFSET_TTL, ttl)
+        self._update_l4_checksum()
+        # don't need to update self.match; no ttl in it
+
+    def dec_nw_ttl(self):
+        if self.ip_header_offset is None:
+            return
+        offset = self.ip_header_offset + Packet.IP_OFFSET_TTL
+        old_ttl = struct.unpack("b",self.data[offset:offset + 1])[0]
+        self.set_nw_ttl( old_ttl - 1)
+
+    #
+    # All action functions need to take the action object for params
+    # These take an action object to facilitate the switch implementation
+    #
+
+    def action_output(self, action, switch):
+        if action.port < ofp.OFPP_MAX:
+            switch.dataplane.send(action.port, self.data, 
+                                  queue_id=self.queue_id)
+        elif action.port == ofp.OFPP_ALL:
+            for of_port in switch.ports.iterkeys():
+                if of_port != self.in_port: 
+                    switch.dataplane.send(of_port, self.data, 
+                                          queue_id=self.queue_id)
+        elif action.port == ofp.OFPP_IN_PORT:
+            switch.dataplane.send(self.in_port, self.data, 
+                                  queue_id=self.queue_id)
+        else:
+            switch.logger.error("NEED to implement action_output" + 
+                                " for port %d" % action.port)        
+
+    def action_set_queue(self, action, switch):
+        self.set_queue(action.queue_id)
+
+    def action_set_vlan_vid(self, action, switch):
+        self.set_vlan_vid(action.vlan_vid)
+
+    def action_set_vlan_pcp(self, action, switch):
+        self.set_vlan_pcp(action.vlan_pcp)
+
+    def action_set_dl_src(self, action, switch):
+        self.set_dl_src(action.dl_addr)
+
+    def action_set_dl_dst(self, action, switch):
+        self.set_dl_dst(action.dl_addr)
+
+    def action_set_nw_src(self, action, switch):
+        self.set_nw_src(action.nw_addr)
+
+    def action_set_nw_dst(self, action, switch):
+        self.set_nw_dst(action.nw_addr)
+
+    def action_set_nw_tos(self, action, switch):
+        self.set_nw_tos(action.nw_tos)
+
+    def action_set_nw_ecn(self, action, switch):
+        self.set_nw_ecn(action.nw_ecn)
+
+    def action_set_tp_src(self, action, switch):
+        self.set_tp_src(action.tp_port)
+
+    def action_set_tp_dst(self, action, switch):
+        self.set_tp_dst(action.tp_port)
+
+    def action_copy_ttl_out(self, action, switch):
+        self.copy_ttl_out()
+
+    def action_copy_ttl_in(self, action, switch):
+        self.copy_ttl_in()
+
+    def action_set_mpls_label(self, action, switch):
+        self.set_mpls_label(action.mpls_label)
+
+    def action_set_mpls_tc(self, action, switch):
+        self.set_mpls_tc(action.mpls_tc)
+
+    def action_set_mpls_ttl(self, action, switch):
+        self.set_mpls_ttl(action.mpls_ttl)
+
+    def action_dec_mpls_ttl(self, action, switch):
+        self.dec_mpls_ttl()
+
+    def action_push_vlan(self, action, switch):
+        self.push_vlan(action.ethertype)
+
+    def action_pop_vlan(self, action, switch):
+        self.pop_vlan()
+
+    def action_push_mpls(self, action, switch):
+        self.push_mpls(action.ethertype)
+
+    def action_pop_mpls(self, action, switch):
+        self.pop_mpls(action.ethertype)
+    
+    def action_experimenter(self, action, switch):
+        pass
+
+    def action_set_nw_ttl(self, action, switch):
+        self.set_nw_ttl(action.nw_ttl)
+
+    def action_dec_nw_ttl(self, action, switch):
+        self.dec_nw_ttl()
+
+    def action_group(self, action, switch):
+        pass
+
+    def execute_action_set(self, switch):
+        """
+        Execute the actions in the action set for the packet
+        according to the order given in ordered_action_list.
+
+        This determines the order in which
+        actions in the packet's action set are executed
+
+        @param switch The parent switch object (for sending pkts out)
+
+        @todo Verify the ordering in this list
+        """
+        cls = action.action_copy_ttl_in
+        if cls in self.action_set.keys():
+            self.logger.debug("Action copy_ttl_in")
+            self.action_copy_ttl_in(self.action_set[cls], switch)
+
+        cls = action.action_pop_mpls
+        if cls in self.action_set.keys():
+            self.logger.debug("Action pop_mpls")
+            self.action_pop_mpls(self.action_set[cls], switch)
+        cls = action.action_pop_vlan
+        if cls in self.action_set.keys():
+            self.logger.debug("Action pop_vlan")
+            self.action_pop_vlan(self.action_set[cls], switch)
+        cls = action.action_push_mpls
+        if cls in self.action_set.keys():
+            self.logger.debug("Action push_mpls")
+            self.action_push_mpls(self.action_set[cls], switch)
+        cls = action.action_push_vlan
+        if cls in self.action_set.keys():
+            self.logger.debug("Action push_vlan")
+            self.action_push_vlan(self.action_set[cls], switch)
+
+        cls = action.action_dec_mpls_ttl
+        if cls in self.action_set.keys():
+            self.logger.debug("Action dec_mpls_ttl")
+            self.action_dec_mpls_ttl(self.action_set[cls], switch)
+        cls = action.action_dec_nw_ttl
+        if cls in self.action_set.keys():
+            self.logger.debug("Action dec_nw_ttl")
+            self.action_dec_nw_ttl(self.action_set[cls], switch)
+        cls = action.action_copy_ttl_out
+        if cls in self.action_set.keys():
+            self.logger.debug("Action copy_ttl_out")
+            self.action_copy_ttl_out(self.action_set[cls], switch)
+
+        cls = action.action_set_dl_dst
+        if cls in self.action_set.keys():
+            self.logger.debug("Action set_dl_dst")
+            self.action_set_dl_dst(self.action_set[cls], switch)
+        cls = action.action_set_dl_src
+        if cls in self.action_set.keys():
+            self.logger.debug("Action set_dl_src")
+            self.action_set_dl_src(self.action_set[cls], switch)
+        cls = action.action_set_mpls_label
+        if cls in self.action_set.keys():
+            self.logger.debug("Action set_mpls_label")
+            self.action_set_mpls_label(self.action_set[cls], switch)
+        cls = action.action_set_mpls_tc
+        if cls in self.action_set.keys():
+            self.logger.debug("Action set_mpls_tc")
+            self.action_set_mpls_tc(self.action_set[cls], switch)
+        cls = action.action_set_mpls_ttl
+        if cls in self.action_set.keys():
+            self.logger.debug("Action set_mpls_ttl")
+            self.action_set_mpls_ttl(self.action_set[cls], switch)
+        cls = action.action_set_nw_dst
+        if cls in self.action_set.keys():
+            self.logger.debug("Action set_nw_dst")
+            self.action_set_nw_dst(self.action_set[cls], switch)
+        cls = action.action_set_nw_ecn
+        if cls in self.action_set.keys():
+            self.logger.debug("Action set_nw_ecn")
+            self.action_set_nw_ecn(self.action_set[cls], switch)
+        cls = action.action_set_nw_src
+        if cls in self.action_set.keys():
+            self.logger.debug("Action set_nw_src")
+            self.action_set_nw_src(self.action_set[cls], switch)
+        cls = action.action_set_nw_tos
+        if cls in self.action_set.keys():
+            self.logger.debug("Action set_nw_tos")
+            self.action_set_nw_tos(self.action_set[cls], switch)
+        cls = action.action_set_nw_ttl
+        if cls in self.action_set.keys():
+            self.logger.debug("Action set_nw_ttl")
+            self.action_set_nw_ttl(self.action_set[cls], switch)
+        cls = action.action_set_queue
+        if cls in self.action_set.keys():
+            self.logger.debug("Action set_queue")
+            self.action_set_queue(self.action_set[cls], switch)
+        cls = action.action_set_tp_dst
+        if cls in self.action_set.keys():
+            self.logger.debug("Action set_tp_dst")
+            self.action_set_tp_dst(self.action_set[cls], switch)
+        cls = action.action_set_tp_src
+        if cls in self.action_set.keys():
+            self.logger.debug("Action set_tp_src")
+            self.action_set_tp_src(self.action_set[cls], switch)
+        cls = action.action_set_vlan_pcp
+        if cls in self.action_set.keys():
+            self.logger.debug("Action set_vlan_pcp")
+            self.action_set_vlan_pcp(self.action_set[cls], switch)
+        cls = action.action_set_vlan_vid
+        if cls in self.action_set.keys():
+            self.logger.debug("Action set_vlan_vid")
+            self.action_set_vlan_vid(self.action_set[cls], switch)
+
+        cls = action.action_group
+        if cls in self.action_set.keys():
+            self.logger.debug("Action group")
+            self.action_group(self.action_set[cls], switch)
+        cls = action.action_experimenter
+        if cls in self.action_set.keys():
+            self.logger.debug("Action experimenter")
+            self.action_experimenter(self.action_set[cls], switch)
+        cls = action.action_output
+        if cls in self.action_set.keys():
+            self.logger.debug("Action set_output")
+            self.action_output(self.action_set[cls], switch)
+
+
+def ascii_ip_to_bin(ip):
+        """ Take '192.168.0.1' and return the NBO decimal equivalent 0xc0a80101 """
+        #Lookup the cleaner, one-line way of doing this
+        # or if there isn't just a library (!?)
+        s = ip.split('.')
+        return struct.unpack("!L", struct.pack("BBBB", int(s[0]), 
+                                               int(s[1]), 
+                                               int(s[2]), 
+                                               int(s[3]) ))[0]
+    
+
+class parse_error(Exception):
+    """
+    Thrown internally if there is an error in packet parsing
+    """
+    
+    def __init__(self, why):
+        self.why = why
+        
+    def __str__(self):
+        return "%s:: %s" % (super.__str__(self), self.why)
+        
+class packet_test(unittest.TestCase):
+    """
+    Unit tests for packet class
+    """
+    
+    def ascii_to_data(self, str):
+        return binascii.unhexlify(str.translate(string.maketrans('',''),
+                                                string.whitespace))
+    
+    def setUp(self):
+        """
+        Simple packet data for parsing tests.  
+
+        Ethernet II, Src: Fujitsu_ef:cd:8d (00:17:42:ef:cd:8d), 
+            Dst: ZhsZeitm_5d:24:00 (00:d0:05:5d:24:00)
+        Internet Protocol, Src: 172.24.74.96 (172.24.74.96), 
+            Dst: 171.64.74.58 (171.64.74.58)
+        Transmission Control Protocol, Src Port: 59581 (59581), 
+            Dst Port: ssh (22), Seq: 2694, Ack: 2749, Len: 48
+        """
+        pktdata = self.ascii_to_data(
+            """00 d0 05 5d 24 00 00 17 42 ef cd 8d 08 00 45 10
+               00 64 65 67 40 00 40 06 e9 29 ac 18 4a 60 ab 40
+               4a 3a e8 bd 00 16 7c 28 2f 88 f2 bd 7a 03 80 18
+               00 b5 ec 49 00 00 01 01 08 0a 00 d1 46 8b 32 ed
+               7c 88 78 4b 8a dc 0a 1f c4 d3 02 a3 ae 1d 3c aa
+               6f 1a 36 9f 27 11 12 71 5b 5d 88 f2 97 fa e7 f9
+               99 c1 9f 9c 7f c5 1e 3e 45 c6 a6 ac ec 0b 87 64
+               98 dd""")
+        self.pkt = Packet(data=pktdata)
+        
+        """
+        MPLS packet data for MPLS parsing tests.  
+
+        Ethernet II, Src: Fujitsu_ef:cd:8d (00:17:42:ef:cd:8d), 
+            Dst: ZhsZeitm_5d:24:00 (00:d0:05:5d:24:00)
+        MPLS, Label: 0xFEFEF, TC: 5, S: 1, TTL: 0xAA
+        Internet Protocol, Src: 172.24.74.96 (172.24.74.96), 
+            Dst: 171.64.74.58 (171.64.74.58)
+        Transmission Control Protocol, Src Port: 59581 (59581), 
+            Dst Port: ssh (22), Seq: 2694, Ack: 2749, Len: 48
+        """
+        mplspktdata = self.ascii_to_data(
+            """00 d0 05 5d 24 00 00 17 42 ef cd 8d 88 47
+               FE FE FB AA
+               45 10 00 64 65 67 40 00 40 06 e9 29 ac 18 4a 60 
+               ab 40 4a 3a 
+               e8 bd 00 16 7c 28 2f 88 f2 bd 7a 03 80 18
+               00 b5 ec 49 00 00 01 01 08 0a 00 d1 46 8b 32 ed
+               7c 88 78 4b 8a dc 0a 1f c4 d3 02 a3 ae 1d 3c aa
+               6f 1a 36 9f 27 11 12 71 5b 5d 88 f2 97 fa e7 f9
+               99 c1 9f 9c 7f c5 1e 3e 45 c6 a6 ac ec 0b 87 64
+               98 dd""")
+        self.mplspkt = Packet(data=mplspktdata)
+
+    def runTest(self):
+        self.assertTrue(self.pkt)
+        
+class l2_parsing_test(packet_test):
+    def runTest(self):
+        match = self.pkt.match
+        self.assertEqual(match.dl_dst,[0x00,0xd0,0x05,0x5d,0x24,0x00])
+        self.assertEqual(match.dl_src,[0x00,0x17,0x42,0xef,0xcd,0x8d])
+        self.assertEqual(match.dl_type,ETHERTYPE_IP)
+        
+class mpls_parsing_test(packet_test):
+    def runTest(self):
+        match = self.mplspkt.match
+        self.assertEqual(match.mpls_label, 0xFEFEF)
+        self.assertEqual(match.mpls_tc, 5)
+
+class ip_parsing_test(packet_test):
+    def runTest(self):
+        match = self.pkt.match
+        # @todo Verify byte ordering of the following
+        self.assertEqual(match.nw_dst,ascii_ip_to_bin('171.64.74.58'))
+        self.assertEqual(match.nw_src,ascii_ip_to_bin('172.24.74.96'))
+        self.assertEqual(match.nw_proto, socket.IPPROTO_TCP)
+
+class mpls_setting_test(packet_test):
+    def runTest(self):
+        orig_len = len(self.mplspkt)
+        label = 0x12345
+        tc = 6
+        ttl = 0x78
+        self.mplspkt.set_mpls_label(label)
+        self.mplspkt.set_mpls_tc(tc)
+        self.mplspkt.set_mpls_ttl(ttl)
+        self.mplspkt.dec_mpls_ttl()
+        self.mplspkt.parse()
+        
+        self.assertEqual(len(self.mplspkt), orig_len)
+        self.assertTrue(self.mplspkt.mpls_tag_offset)
+        match = self.mplspkt.match
+        
+        self.assertEqual(match.mpls_label, label)
+        self.assertEqual(match.mpls_tc, tc)
+        new_ttl = struct.unpack("B", self.mplspkt.data[self.mplspkt.mpls_tag_offset + 3:
+                                                       self.mplspkt.mpls_tag_offset + 4])[0]
+        self.assertEqual(new_ttl, ttl - 1)
+
+class mpls_pop_test(packet_test):
+    def runTest(self):
+        orig_len = len(self.mplspkt)
+        self.mplspkt.pop_mpls(ETHERTYPE_IP)
+        self.mplspkt.parse()
+        
+        self.assertEqual(len(self.mplspkt), orig_len - 4)
+        self.assertFalse(self.mplspkt.mpls_tag_offset)
+        match = self.mplspkt.match
+        
+        self.assertEqual(match.dl_type,ETHERTYPE_IP)
+        self.assertEqual(match.nw_dst,ascii_ip_to_bin('171.64.74.58'))
+        self.assertEqual(match.nw_src,ascii_ip_to_bin('172.24.74.96'))
+        self.assertEqual(match.nw_proto, socket.IPPROTO_TCP)
+        
+class mpls_push_test(packet_test):
+    def runTest(self):
+        orig_len = len(self.pkt)
+        self.pkt.push_mpls(ETHERTYPE_MPLS)
+        self.pkt.parse()
+        
+        self.assertEqual(len(self.pkt), orig_len + 4)
+        self.assertTrue(self.pkt.mpls_tag_offset)
+        match = self.pkt.match
+        
+        self.assertEqual(match.dl_type, ETHERTYPE_MPLS)
+        self.assertEqual(match.mpls_label, 0)
+        self.assertEqual(match.mpls_tc, 0)
+
+class ip_setting_test(packet_test):
+    def runTest(self):
+        orig_len = len(self.pkt)
+        ip1 = '11.22.33.44'
+        ip2 = '55.66.77.88'
+        self.pkt.set_nw_src(ascii_ip_to_bin(ip1))
+        self.pkt.set_nw_dst(ascii_ip_to_bin(ip2))
+        self.pkt.parse()
+        self.assertEqual(len(self.pkt), orig_len)
+        match = self.pkt.match
+        
+        # @todo Verify byte ordering of the following
+        self.assertEqual(match.nw_src,ascii_ip_to_bin(ip1))
+        self.assertEqual(match.nw_dst,ascii_ip_to_bin(ip2))
+        
+
+
+
+class l4_parsing_test(packet_test):
+    def runTest(self):
+        match = self.pkt.match
+        self.assertEqual(match.tp_dst,22)
+        self.assertEqual(match.tp_src,59581)
+
+class l4_setting_test(packet_test):
+    def runTest(self):
+        orig_len = len(self.pkt)
+        self.pkt.set_tp_src(777)
+        self.pkt.set_tp_dst(666)
+        self.pkt.parse()
+        self.assertEqual(len(self.pkt), orig_len)
+        match = self.pkt.match
+        self.assertEqual(match.tp_src,777)
+        self.assertEqual(match.tp_dst,666)
+        
+class simple_tcp_test(unittest.TestCase):
+    """ Make sure that simple_tcp_test does what it should 
+                          pktlen=100, 
+                          dl_dst='00:01:02:03:04:05',
+                          dl_src='00:06:07:08:09:0a',
+                          dl_vlan_enable=False,
+                          dl_vlan=0,
+                          dl_vlan_pcp=0,
+                          dl_vlan_cfi=0,
+                          ip_src='192.168.0.1',
+                          ip_dst='192.168.0.2',
+                          ip_tos=0,
+                          tcp_sport=1234,
+                          tcp_dport=80):
+    """
+    def setUp(self):
+        self.pkt = Packet().simple_tcp_packet()
+        self.pkt.parse()
+        logging.basicConfig(filename="", level=logging.DEBUG)
+        self.logger = logging.getLogger('unittest')
+       
+    def runTest(self):
+        match = self.pkt.match
+        self.assertEqual(match.dl_dst, [0x00, 0x01, 0x02, 0x03, 0x04, 0x05])
+        self.assertEqual(match.dl_src, [0x00, 0x06, 0x07, 0x08, 0x09, 0x0a])
+        self.assertEqual(match.dl_type, ETHERTYPE_IP)
+        self.assertEqual(match.nw_src, ascii_ip_to_bin('192.168.0.1'))
+        self.assertEqual(match.nw_dst, ascii_ip_to_bin('192.168.0.2'))
+        self.assertEqual(match.tp_dst, 80)
+        self.assertEqual(match.tp_src, 1234)
+
+class simple_vlan_test(simple_tcp_test):
+    """ Make sure that simple_tcp_test does what it should with vlans 
+                         
+    """    
+       
+    def runTest(self):
+        self.pkt = Packet().simple_tcp_packet(dl_vlan_enable=True,dl_vlan=0x0abc)
+        self.pkt.parse()
+        match = self.pkt.match
+        #self.logger.debug("Packet=\n%s" % self.pkt.show())
+        self.assertEqual(match.dl_dst, [0x00, 0x01, 0x02, 0x03, 0x04, 0x05])
+        self.assertEqual(match.dl_src, [0x00, 0x06, 0x07, 0x08, 0x09, 0x0a])
+        self.assertEqual(match.dl_type, ETHERTYPE_IP)
+        self.assertEqual(match.nw_src, ascii_ip_to_bin('192.168.0.1'))
+        self.assertEqual(match.nw_dst, ascii_ip_to_bin('192.168.0.2'))
+        self.assertEqual(match.tp_dst, 80)
+        self.assertEqual(match.tp_src, 1234)
+        self.assertEqual(match.dl_vlan, 0xabc)
+        
+class vlan_mod(simple_tcp_test):
+    """ Start with a packet with no vlan, add one, change it, remove it"""
+    def runTest(self):
+        old_len = len(self.pkt)
+        match = self.pkt.match
+        self.assertEqual(match.dl_vlan, 0xffff)
+        self.assertEqual(len(self.pkt), old_len)
+        #self.logger.debug("PKT=\n" + self.pkt.show())
+        self.pkt.push_vlan(ETHERTYPE_VLAN) # implicitly pushes vid=0
+        self.assertEqual(len(self.pkt), old_len + 4)
+        self.assertEqual(match.dl_vlan, 0)
+        #self.logger.debug("PKT=\n" + self.pkt.show())
+        self.assertEqual(match.dl_type,ETHERTYPE_IP)
+        self.pkt.set_vlan_vid(0xbabe)
+        self.assertEqual(match.dl_vlan, 0x0abe)
+
+class simple_tcp_with_mpls_test(unittest.TestCase):
+    """ Make sure that simple_tcp_packet does what it should 
+                          pktlen=100, 
+                          dl_dst='00:01:02:03:04:05',
+                          dl_src='00:06:07:08:09:0a',
+                          dl_vlan_enable=False,
+                          dl_vlan=0,
+                          dl_vlan_pcp=0,
+                          dl_vlan_cfi=0,
+                          ip_src='192.168.0.1',
+                          ip_dst='192.168.0.2',
+                          ip_tos=0,
+                          tcp_sport=1234,
+                          tcp_dport=80):
+    """
+    def setUp(self):
+        tag1 = MplsTag(0xabcde, 0x5, 0xAA)
+        tag2 = MplsTag(0x54321, 0x2, 0xBB)
+        mpls_tags = (tag1, tag2)        
+        
+        self.pkt = Packet().simple_tcp_packet(mpls_type=ETHERTYPE_MPLS,
+                                              mpls_tags=mpls_tags)
+        self.pkt.parse()
+       
+    def runTest(self):
+        match = self.pkt.match
+        self.assertEqual(match.dl_dst, [0x00, 0x01, 0x02, 0x03, 0x04, 0x05])
+        self.assertEqual(match.dl_src, [0x00, 0x06, 0x07, 0x08, 0x09, 0x0a])
+        self.assertEqual(match.dl_type, ETHERTYPE_MPLS)
+        self.assertEqual(match.mpls_label, 0xabcde)
+        self.assertEqual(match.mpls_tc, 0x5)
+
+if __name__ == '__main__':
+    print("Running packet tests\n")
+    unittest.main()
+
diff --git a/Fabric/Utilities/src/python/oftest/oft12/testutils.py b/Fabric/Utilities/src/python/oftest/oft12/testutils.py
new file mode 100644
index 0000000..3ce2e75
--- /dev/null
+++ b/Fabric/Utilities/src/python/oftest/oft12/testutils.py
@@ -0,0 +1,1518 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+
+import sys
+import logging
+from cStringIO import StringIO
+#import types
+
+import ofp
+import oftest.parse as parse
+from packet import Packet
+
+try:
+    logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
+    from scapy.all import *
+    from oftest.mpls import *
+except ImportError:
+    sys.exit("Need to install scapy for packet parsing")
+
+global skipped_test_count
+skipped_test_count = 0
+
+# Some useful defines
+IP_ETHERTYPE = 0x800
+IPV6_ETHERTYPE = 0x86dd
+ETHERTYPE_VLAN = 0x8100
+ETHERTYPE_MPLS = 0x8847
+TCP_PROTOCOL = 0x6
+UDP_PROTOCOL = 0x11
+ICMPV6_PROTOCOL = 0x3a
+
+
+
+def clear_switch(parent, port_list, logger):
+    """
+    Clear the switch configuration
+
+    @param parent Object implementing controller and assert equal
+    @param logger Logging object
+    """
+    parent.assertTrue(len(port_list) > 2, "Not enough ports for test")
+    for port in port_list:
+        clear_port_config(parent, port, logger)
+    initialize_table_config(parent.controller, logger)
+    delete_all_flows(parent.controller, logger)
+    delete_all_groups(parent.controller, logger)
+
+    return port_list
+
+def initialize_table_config(ctrl, logger):
+    """
+    Initialize all table configs to default setting ("CONTROLLER")
+    @param ctrl The controller object for the test
+    """
+    logger.info("Initializing all table configs")
+    request = ofp.message.table_mod()  
+    request.config = ofp.OFPTC_TABLE_MISS_CONTROLLER
+    rv = 0
+    for table_id in [0, 1, 2, 3, 4, 5, 6, 7]:
+        request.table_id = table_id
+        rv |= ctrl.message_send(request)
+    return rv
+
+def delete_all_flows(ctrl, logger):
+    """
+    Delete all flows on the switch
+    @param ctrl The controller object for the test
+    @param logger Logging object
+    """
+
+    logger.info("Deleting all flows")
+    #DEFAULT_TABLE_COUNT = 4
+    return delete_all_flows_one_table(ctrl, logger, table_id=0xff)
+
+def delete_all_flows_one_table(ctrl, logger, table_id=0):
+    """
+    Delete all flows on a table
+    @param ctrl The controller object for the test
+    @param logger Logging object
+    @param table_id Table ID
+    """
+    logger.info("Deleting all flows on table ID: " + str(table_id))
+    msg = ofp.message.flow_delete()
+    msg.out_port = ofp.OFPP_ANY
+    msg.out_group = ofp.OFPG_ANY
+    msg.buffer_id = 0xffffffff
+    msg.table_id = table_id
+    logger.debug(msg.show())
+
+    return ctrl.message_send(msg)
+
+def delete_all_groups(ctrl, logger):
+    """
+    Delete all groups on the switch
+    @param ctrl The controller object for the test
+    @param logger Logging object
+    """
+    
+    logger.info("Deleting all groups")
+    msg = ofp.message.group_mod()
+    msg.group_id = ofp.OFPG_ALL
+    msg.command = ofp.OFPGC_DELETE
+    logger.debug(msg.show())
+    return ctrl.message_send(msg)
+
+def clear_port_config(parent, port, logger):
+    """
+    Clear the port configuration 
+
+    @param parent Object implementing controller and assert equal
+    @param logger Logging object
+    """
+    rv = port_config_set(parent.controller, port,
+                         0, 0, logger)
+    parent.assertEqual(rv, 0, "Failed to reset port config")
+
+def simple_tcp_packet(dl_dst='00:01:02:03:04:05',
+                      dl_src='00:06:07:08:09:0a',
+                      vlan_tags=[],  # {type,vid,pcp,cfi}  TODO type
+                      mpls_tags=[],  # {type,label,tc,ttl} TODO type 
+                      ip_src='192.168.0.1',
+                      ip_dst='192.168.0.2',
+                      ip_tos=0,
+                      ip_ttl=64,
+                      tcp_sport=1234,
+                      tcp_dport=80,
+                      payload_len = 46):
+    pkt = Ether(dst=dl_dst, src=dl_src)
+
+    vlans_num = 0
+    while len(vlan_tags):
+        tag = vlan_tags.pop(0)
+        dot1q = Dot1Q()
+        if 'vid' in tag:
+            dot1q.vlan = tag['vid']
+        if 'pcp' in tag:
+            dot1q.prio = tag['pcp']
+        if 'cfi' in tag:
+            dot1q.id = tag['cfi']
+        pkt = pkt / dot1q 
+        if 'type' in tag:
+            if vlans_num == 0:
+                pkt[Ether].setfieldval('type', tag['type'])
+            else:
+                pkt[Dot1Q:vlans_num].setfieldval('type', tag['type'])
+        vlans_num+=1
+
+    mplss_num = 0
+    while len(mpls_tags):
+        tag = mpls_tags.pop(0)
+        mpls = MPLS()
+        if 'label' in tag:
+            mpls.label = tag['label']
+        if 'tc' in tag:
+            mpls.cos = tag['tc']
+        if 'ttl' in tag:
+            mpls.ttl = tag['ttl']
+        pkt = pkt / mpls
+        if 'type' in tag:
+            if mplss_num == 0:
+                if vlans_num == 0:
+                    pkt[Ether].setfieldval('type', tag['type'])
+                else:
+                    pkt[Dot1Q:vlans_num].setfieldval('type', tag['type'])
+        mplss_num+=1
+
+    pkt = pkt / IP(src=ip_src, dst=ip_dst, tos=ip_tos, ttl=ip_ttl) \
+              / TCP(sport=tcp_sport, dport=tcp_dport)
+    
+    pkt = pkt / ("D" * payload_len)
+
+    return pkt
+
+def simple_icmp_packet(dl_dst='00:01:02:03:04:05',
+                       dl_src='00:06:07:08:09:0a',
+                       vlan_tags=[],  # {type,vid,pcp,cfi}  TODO type
+                       mpls_tags=[],  # {type,label,tc,ttl} TODO type 
+                       ip_src='192.168.0.1',
+                       ip_dst='192.168.0.2',
+                       ip_tos=0,
+                       ip_ttl=64,
+                       icmp_type=8, # ICMP_ECHO_REQUEST
+                       icmp_code=0,
+                       payload_len=0):
+
+    #TODO simple_ip_packet
+    pkt = Ether(dst=dl_dst, src=dl_src)
+
+    vlans_num = 0
+    while len(vlan_tags):
+        tag = vlan_tags.pop(0)
+        dot1q = Dot1Q()
+        if 'vid' in tag:
+            dot1q.vlan = tag['vid']
+        if 'pcp' in tag:
+            dot1q.prio = tag['pcp']
+        if 'cfi' in tag:
+            dot1q.id = tag['cfi']
+        pkt = pkt / dot1q 
+        if 'type' in tag:
+            if vlans_num == 0:
+                pkt[Ether].setfieldval('type', tag['type'])
+            else:
+                pkt[Dot1Q:vlans_num].setfieldval('type', tag['type'])
+        vlans_num+=1
+
+    mplss_num = 0
+    while len(mpls_tags):
+        tag = mpls_tags.pop(0)
+        mpls = MPLS()
+        if 'label' in tag:
+            mpls.label = tag['label']
+        if 'tc' in tag:
+            mpls.cos = tag['tc']
+        if 'ttl' in tag:
+            mpls.ttl = tag['ttl']
+        pkt = pkt / mpls
+        if 'type' in tag:
+            if mplss_num == 0:
+                if vlans_num == 0:
+                    pkt[Ether].setfieldval('type', tag['type'])
+                else:
+                    pkt[Dot1Q:vlans_num].setfieldval('type', tag['type'])
+        mplss_num+=1
+
+    pkt = pkt / IP(src=ip_src, dst=ip_dst, tos=ip_tos, ttl=ip_ttl) \
+              / ICMP(type=icmp_type, code=icmp_code)
+
+    pkt = pkt / ("D" * payload_len)
+
+    return pkt
+
+def simple_ipv6_packet(pktlen=100, 
+                      dl_dst='00:01:02:03:04:05',
+                      dl_src='00:06:07:08:09:0a',
+                      dl_vlan_enable=False,
+                      dl_vlan=0,
+                      dl_vlan_pcp=0,
+                      dl_vlan_cfi=0,
+                      ip_src='fe80::2420:52ff:fe8f:5189',
+                      ip_dst='fe80::2420:52ff:fe8f:5190',
+                      ip_tos=0,
+                      tcp_sport=0,
+                      tcp_dport=0, 
+                      EH = False, 
+                      EHpkt = IPv6ExtHdrDestOpt()
+                      ):
+
+    """
+    Return a simple IPv6 packet 
+
+    Supports a few parameters:
+    @param len Length of packet in bytes w/o CRC
+    @param dl_dst Destinatino MAC
+    @param dl_src Source MAC
+    @param dl_vlan_enable True if the packet is with vlan, False otherwise
+    @param dl_vlan VLAN ID
+    @param dl_vlan_pcp VLAN priority
+    @param ip_src IPv6 source
+    @param ip_dst IPv6 destination
+    @param ip_tos IP ToS
+    @param tcp_dport TCP destination port
+    @param ip_sport TCP source port
+
+    """
+    # Note Dot1Q.id is really CFI
+    if (dl_vlan_enable):
+        pkt = Ether(dst=dl_dst, src=dl_src)/ \
+            Dot1Q(prio=dl_vlan_pcp, id=dl_vlan_cfi, vlan=dl_vlan)/ \
+            IPv6(src=ip_src, dst=ip_dst)
+
+    else:
+        pkt = Ether(dst=dl_dst, src=dl_src)/ \
+            IPv6(src=ip_src, dst=ip_dst)
+
+    # Add IPv6 Extension Headers 
+    if EH:
+        pkt = pkt / EHpkt
+
+    if (tcp_sport >0 and tcp_dport >0):
+        pkt = pkt / TCP(sport=tcp_sport, dport=tcp_dport)
+
+    if pktlen > len(pkt) :
+        pkt = pkt/("D" * (pktlen - len(pkt)))
+
+    return pkt
+
+def simple_icmpv6_packet(pktlen=100, 
+                      dl_dst='00:01:02:03:04:05',
+                      dl_src='00:06:07:08:09:0a',
+                      dl_vlan_enable=False,
+                      dl_vlan=0,
+                      dl_vlan_pcp=0,
+                      dl_vlan_cfi=0,
+                      ip_src='fe80::2420:52ff:fe8f:5189',
+                      ip_dst='fe80::2420:52ff:fe8f:5190',
+                      ip_tos=0,
+                      tcp_sport=0,
+                      tcp_dport=0, 
+                      EH = False, 
+                      EHpkt = IPv6ExtHdrDestOpt(),
+                      route_adv = False,
+                      sll_enabled = False
+                      ):
+
+    """
+    Return a simple dataplane ICMPv6 packet 
+
+    Supports a few parameters:
+    @param len Length of packet in bytes w/o CRC
+    @param dl_dst Destinatino MAC
+    @param dl_src Source MAC
+    @param dl_vlan_enable True if the packet is with vlan, False otherwise
+    @param dl_vlan VLAN ID
+    @param dl_vlan_pcp VLAN priority
+    @param ip_src IPv6 source
+    @param ip_dst IPv6 destination
+    @param ip_tos IP ToS
+    @param tcp_dport TCP destination port
+    @param ip_sport TCP source port
+    
+    """
+    if (dl_vlan_enable):
+        pkt = Ether(dst=dl_dst, src=dl_src)/ \
+            Dot1Q(prio=dl_vlan_pcp, id=dl_vlan_cfi, vlan=dl_vlan)/ \
+            IPv6(src=ip_src, dst=ip_dst)
+
+    else:
+        pkt = Ether(dst=dl_dst, src=dl_src)/ \
+            IPv6(src=ip_src, dst=ip_dst)
+            
+            
+    # Add IPv6 Extension Headers 
+    if EH:
+        pkt = pkt / EHpkt
+
+    if route_adv:
+        pkt = pkt/ \
+        ICMPv6ND_RA(chlim=255, H=0L, M=0L, O=1L, routerlifetime=1800, P=0L, retranstimer=0, prf=0L, res=0L)/ \
+        ICMPv6NDOptPrefixInfo(A=1L, res2=0, res1=0L, L=1L, len=4, prefix='fd00:141:64:1::', R=0L, validlifetime=1814400, prefixlen=64, preferredlifetime=604800, type=3)
+        if sll_enabled :
+            pkt = pkt/ \
+            ICMPv6NDOptSrcLLAddr(type=1, len=1, lladdr='66:6f:df:2d:7c:9c')
+    else :
+        pkt = pkt/ \
+            ICMPv6EchoRequest()
+    if (tcp_sport >0 and tcp_dport >0):
+        pkt = pkt / TCP(sport=tcp_sport, dport=tcp_dport)
+
+    if pktlen > len(pkt) :
+        pkt = pkt/("D" * (pktlen - len(pkt)))
+
+    return pkt
+
+
+def do_barrier(ctrl):
+    b = ofp.message.barrier_request()
+    ctrl.transact(b)
+
+
+def port_config_get(controller, port_no, logger):
+    """
+    Get a port's configuration
+
+    Gets the switch feature configuration and grabs one port's
+    configuration
+
+    @returns (hwaddr, config, advert) The hwaddress, configuration and
+    advertised values
+    """
+    request = ofp.message.features_request()
+    reply, _ = controller.transact(request, timeout=2)
+    if reply is None:
+        logger.warn("Get feature request failed")
+        return None, None, None
+    logger.debug(reply.show())
+    for idx in range(len(reply.ports)):
+        if reply.ports[idx].port_no == port_no:
+            return (reply.ports[idx].hw_addr, reply.ports[idx].config,
+                    reply.ports[idx].advertised)
+    
+    logger.warn("Did not find port number for port config")
+    return None, None, None
+
+def port_config_set(controller, port_no, config, mask, logger):
+    """
+    Set the port configuration according the given parameters
+
+    Gets the switch feature configuration and updates one port's
+    configuration value according to config and mask
+    """
+    logger.info("Setting port " + str(port_no) + " to config " + str(config))
+    request = ofp.message.features_request()
+    reply, _ = controller.transact(request, timeout=2)
+    if reply is None:
+        return -1
+    logger.debug(reply.show())
+    for idx in range(len(reply.ports)):
+        if reply.ports[idx].port_no == port_no:
+            break
+    if idx >= len(reply.ports):
+        return -1
+    mod = ofp.message.port_mod()
+    mod.port_no = port_no
+    mod.hw_addr = reply.ports[idx].hw_addr
+    mod.config = config
+    mod.mask = mask
+    mod.advertise = reply.ports[idx].advertised
+    rv = controller.message_send(mod)
+    return rv
+
+def receive_pkt_check(dataplane, pkt, yes_ports, no_ports, assert_if, logger):
+    """
+    Check for proper receive packets across all ports
+    @param dataplane The dataplane object
+    @param pkt Expected packet; may be None if yes_ports is empty
+    @param yes_ports Set or list of ports that should recieve packet
+    @param no_ports Set or list of ports that should not receive packet
+    @param assert_if Object that implements assertXXX
+    """
+    for ofport in yes_ports:
+        logger.debug("Checking for pkt on port " + str(ofport))
+        (_, rcv_pkt, _) = dataplane.poll(
+            port_number=ofport, timeout=1)
+        assert_if.assertTrue(rcv_pkt is not None, 
+                             "Did not receive pkt on " + str(ofport))
+        assert_if.assertEqual(str(pkt), str(rcv_pkt),
+                              "Response packet does not match send packet " +
+                              "on port " + str(ofport))
+
+    for ofport in no_ports:
+        logger.debug("Negative check for pkt on port " + str(ofport))
+        (_, rcv_pkt, _) = dataplane.poll(
+            port_number=ofport, timeout=1)
+        assert_if.assertTrue(rcv_pkt is None, 
+                             "Unexpected pkt on port " + str(ofport))
+
+
+def pkt_verify(parent, rcv_pkt, exp_pkt):
+    if str(exp_pkt) != str(rcv_pkt):
+        logging.error("ERROR: Packet match failed.")
+        logging.debug("Expected (" + str(len(exp_pkt)) + ")")
+        logging.debug(str(exp_pkt).encode('hex'))
+        sys.stdout = tmpout = StringIO()
+        exp_pkt.show()
+        sys.stdout = sys.__stdout__
+        logging.debug(tmpout.getvalue())
+        logging.debug("Received (" + str(len(rcv_pkt)) + ")")
+        logging.debug(str(rcv_pkt).encode('hex'))
+        sys.stdout = tmpout = StringIO()
+        Ether(rcv_pkt).show()
+        sys.stdout = sys.__stdout__
+        logging.debug(tmpout.getvalue())
+    parent.assertEqual(str(exp_pkt), str(rcv_pkt),
+                       "Packet match error")
+    
+    return rcv_pkt
+
+def receive_pkt_verify(parent, egr_port, exp_pkt):
+    """
+    Receive a packet and verify it matches an expected value
+
+    parent must implement dataplane, assertTrue and assertEqual
+    """
+    (rcv_port, rcv_pkt, _) = parent.dataplane.poll(port_number=egr_port,
+                                                          timeout=1)
+
+    if exp_pkt is None:
+        if rcv_pkt is None:
+            return None
+        else:
+            logging.error("ERROR: Received unexpected packet from " + str(egr_port));
+            return rcv_pkt
+
+    if rcv_pkt is None:
+        logging.error("ERROR: No packet received from " + str(egr_port))
+
+    parent.assertTrue(rcv_pkt is not None,
+                      "Did not receive packet port " + str(egr_port))
+    logging.debug("Packet len " + str(len(rcv_pkt)) + " in on " + 
+                    str(rcv_port))
+
+    return pkt_verify(parent, rcv_pkt, exp_pkt)
+
+def packetin_verify(parent, exp_pkt):
+    """
+    Receive packet_in and verify it matches an expected value
+    """
+    (response, _) = parent.controller.poll(ofp.OFPT_PACKET_IN, 2)
+
+    parent.assertTrue(response is not None, 'Packet in ofp.message not received')
+    if str(exp_pkt) != response.data:
+        logging.debug("pkt  len " + str(len(str(exp_pkt))) + ": "
+                            + str(exp_pkt).encode('hex'))
+        logging.debug("resp len " + str(len(str(response.data))) + ": "
+                            + str(response.data).encode('hex'))
+    parent.assertEqual(str(exp_pkt), response.data,
+                     'PACKET_IN packet does not match send packet')
+
+def match_verify(parent, req_match, res_match):
+    """
+    Verify flow matches agree; if they disagree, report where
+
+    parent must implement assertEqual
+    Use str() to ensure content is compared and not pointers
+    """
+
+    parent.assertEqual(req_match.wildcards, res_match.wildcards,
+                       'Match failed: wildcards: ' + hex(req_match.wildcards) +
+                       " != " + hex(res_match.wildcards))
+    parent.assertEqual(req_match.in_port, res_match.in_port,
+                       'Match failed: in_port: ' + str(req_match.in_port) +
+                       " != " + str(res_match.in_port))
+    parent.assertEqual(str(req_match.dl_src), str(res_match.dl_src),
+                       'Match failed: dl_src: ' + str(req_match.dl_src) +
+                       " != " + str(res_match.dl_src))
+    parent.assertEqual(str(req_match.dl_dst), str(res_match.dl_dst),
+                       'Match failed: dl_dst: ' + str(req_match.dl_dst) +
+                       " != " + str(res_match.dl_dst))
+    parent.assertEqual(req_match.dl_vlan, res_match.dl_vlan,
+                       'Match failed: dl_vlan: ' + str(req_match.dl_vlan) +
+                       " != " + str(res_match.dl_vlan))
+    parent.assertEqual(req_match.dl_vlan_pcp, res_match.dl_vlan_pcp,
+                       'Match failed: dl_vlan_pcp: ' + 
+                       str(req_match.dl_vlan_pcp) + " != " + 
+                       str(res_match.dl_vlan_pcp))
+    parent.assertEqual(req_match.dl_type, res_match.dl_type,
+                       'Match failed: dl_type: ' + str(req_match.dl_type) +
+                       " != " + str(res_match.dl_type))
+
+    if (not(req_match.wildcards & ofp.OFPFW_DL_TYPE)
+        and (req_match.dl_type == IP_ETHERTYPE)):
+        parent.assertEqual(req_match.nw_tos, res_match.nw_tos,
+                           'Match failed: nw_tos: ' + str(req_match.nw_tos) +
+                           " != " + str(res_match.nw_tos))
+        parent.assertEqual(req_match.nw_proto, res_match.nw_proto,
+                           'Match failed: nw_proto: ' + str(req_match.nw_proto) +
+                           " != " + str(res_match.nw_proto))
+        parent.assertEqual(req_match.nw_src, res_match.nw_src,
+                           'Match failed: nw_src: ' + str(req_match.nw_src) +
+                           " != " + str(res_match.nw_src))
+        parent.assertEqual(req_match.nw_dst, res_match.nw_dst,
+                           'Match failed: nw_dst: ' + str(req_match.nw_dst) +
+                           " != " + str(res_match.nw_dst))
+
+        if (not(req_match.wildcards & ofp.OFPFW_NW_PROTO)
+            and ((req_match.nw_proto == TCP_PROTOCOL)
+                 or (req_match.nw_proto == UDP_PROTOCOL))):
+            parent.assertEqual(req_match.tp_src, res_match.tp_src,
+                               'Match failed: tp_src: ' + 
+                               str(req_match.tp_src) +
+                               " != " + str(res_match.tp_src))
+            parent.assertEqual(req_match.tp_dst, res_match.tp_dst,
+                               'Match failed: tp_dst: ' + 
+                               str(req_match.tp_dst) +
+                               " != " + str(res_match.tp_dst))
+
+def flow_removed_verify(parent, request=None, pkt_count=-1, byte_count=-1):
+    """
+    Receive a flow removed msg and verify it matches expected
+
+    @params parent Must implement controller, assertEqual
+    @param pkt_count If >= 0, verify packet count
+    @param byte_count If >= 0, verify byte count
+    """
+    (response, _) = parent.controller.poll(ofp.OFPT_FLOW_REMOVED, 2)
+    parent.assertTrue(response is not None, 'No flow removed ofp.message received')
+
+    if request is None:
+        return
+
+    parent.assertEqual(request.cookie, response.cookie,
+                       "Flow removed cookie error: " +
+                       hex(request.cookie) + " != " + hex(response.cookie))
+
+    req_match = request.match
+    res_match = response.match
+    verifyMatchField(req_match, res_match)
+
+    if (req_match.wildcards != 0):
+        parent.assertEqual(request.priority, response.priority,
+                           'Flow remove prio mismatch: ' + 
+                           str(request.priority) + " != " + 
+                           str(response.priority))
+        parent.assertEqual(response.reason, ofp.OFPRR_HARD_TIMEOUT,
+                           'Flow remove reason is not HARD TIMEOUT:' +
+                           str(response.reason))
+        if pkt_count >= 0:
+            parent.assertEqual(response.packet_count, pkt_count,
+                               'Flow removed failed, packet count: ' + 
+                               str(response.packet_count) + " != " +
+                               str(pkt_count))
+        if byte_count >= 0:
+            parent.assertEqual(response.byte_count, byte_count,
+                               'Flow removed failed, byte count: ' + 
+                               str(response.byte_count) + " != " + 
+                               str(byte_count))
+def flow_msg_create(parent, pkt, ing_port=0, match_fields=None, instruction_list=None, 
+                    action_list=None,wildcards=0, egr_port=None, 
+                    egr_queue=None, table_id=0, check_expire=False):
+    """
+    Multi-purpose flow_mod creation utility
+
+    Match on packet with given wildcards.  
+    See flow_match_test for other parameter descriptoins
+   
+    if egr_queue is set
+             append an out_queue ofp.action to egr_queue to the actions_list
+    else if egr_port is set:  
+             append an output ofp.action to egr_port to the actions_list
+    if the instruction_list is empty, 
+        append an APPLY ofp.instruction to it
+    Add the action_list to the first write or apply ofp.instruction
+    
+    @param egr_queue if not None, make the output an enqueue ofp.action
+    @param table_id Table ID for writing a flow_mod
+    """
+
+    if match_fields is None:
+        match_fields = parse.packet_to_flow_match(pkt)
+    parent.assertTrue(match_fields is not None, "Flow match from pkt failed")
+    in_port = ofp.oxm.in_port(ing_port)
+    match_fields.oxm_list.append(in_port) 
+    request = ofp.message.flow_add()
+    request.match= match_fields
+    request.buffer_id = 0xffffffff
+    request.table_id = table_id
+    
+    if check_expire:
+        request.flags |= ofp.OFPFF_SEND_FLOW_REM
+        request.hard_timeout = 1    
+    
+    if action_list is None:
+        action_list = []
+    if instruction_list is None:
+        instruction_list = []
+    
+    # Set up output/enqueue ofp.action if directed
+    if egr_queue is not None:
+        parent.assertTrue(egr_port is not None, "Egress port not set")
+        act = ofp.action.set_queue()
+        act.port = egr_port
+        act.queue_id = egr_queue
+        action_list.append(act)
+    elif egr_port is not None:
+        act = ofp.action.output()
+        act.port = egr_port
+        action_list.append(act)
+        
+    inst = None
+    if len(instruction_list) == 0: 
+        inst = ofp.instruction.apply_actions()
+        instruction_list.append(inst)
+    else:
+        for inst in instruction_list:
+            if (inst.type == ofp.OFPIT_WRITE_ACTIONS or
+                inst.type == ofp.OFPIT_APPLY_ACTIONS):
+                break
+
+
+    # add all the actions to the last inst
+    inst.actions += action_list
+
+    # add all the instrutions to the flow_mod
+    request.instructions += instruction_list
+ 
+    logging.debug(request.show())
+    return request
+
+def flow_msg_install(parent, request, clear_table=True):
+    """
+    Install a flow mod ofp.message in the switch
+
+    @param parent Must implement controller, assertEqual, assertTrue
+    @param request The request, all set to go
+    @param clear_table If true, clear the flow table before installing
+    """
+    if clear_table:
+        logging.debug("Clear flow table")
+        if request.table_id:
+            table_id = request.table_id
+        else:
+            table_id = 0
+        rc = delete_all_flows_one_table(parent.controller,
+                                        logging,
+                                        table_id)
+        parent.assertEqual(rc, 0, "Failed to delete all flows on table: "
+                           + str(table_id))
+        do_barrier(parent.controller)
+
+    logging.debug("Insert flow::\n%s" % request.show())
+    rv = parent.controller.message_send(request)
+    parent.assertTrue(rv != -1, "Error installing flow mod")
+    do_barrier(parent.controller)
+
+def error_verify(parent, exp_type, exp_code):
+    """
+    Receive an error msg and verify if it is as expected
+
+    @param parent Must implement controller, assertEqual
+    @param exp_type Expected error type
+    @param exp_code Expected error code
+    """
+    (response, raw) = parent.controller.poll(ofp.OFPT_ERROR, 2)
+    parent.assertTrue(response is not None, 'No error ofp.message received')
+
+    if (exp_type is None) or (exp_code is None):
+        logging.debug("Parametrs are not sufficient")
+        return
+
+    parent.assertEqual(exp_type, response.type,
+                       'Error ofp.message type mismatch: ' +
+                       str(exp_type) + " != " +
+                       str(response.type))
+    parent.assertEqual(exp_code, response.code,
+                       'Error ofp.message code mismatch: ' +
+                       str(exp_code) + " != " +
+                       str(response.code))
+
+def flow_match_test_port_pair(parent, ing_port, egr_port, match=None, 
+                              wildcards=0, mask=None,
+                              dl_vlan=-1, pkt=None, exp_pkt=None,
+                              apply_action_list=None, check_expire=False):
+    """
+    Flow match test on single TCP packet
+
+    Run test with packet through switch from ing_port to egr_port
+    See flow_match_test for parameter descriptions
+    """
+
+    logging.info("Pkt match test: " + str(ing_port) + " to " + str(egr_port))
+    logging.debug("  WC: " + hex(wildcards) + " vlan: " + str(dl_vlan) +
+                    " expire: " + str(check_expire))
+    if pkt is None:
+        if dl_vlan >= 0:
+            pkt = simple_tcp_packet(vlan_tags=[{'vid': dl_vlan}])
+        else:
+            pkt = simple_tcp_packet()
+
+    match = parse.packet_to_flow_match(pkt)
+    parent.assertTrue(match is not None, "Flow match from pkt failed")
+
+    if mask is not None:
+        match.dl_src_mask = mask['dl_src']
+        match.dl_dst_mask = mask['dl_dst']
+        match.nw_src_mask = mask['nw_src']
+        match.nw_dst_mask = mask['nw_dst']
+        #Set unmatching values on corresponding match fields
+        for i in range(ofp.OFP_ETH_ALEN):
+            match.dl_src[i] = match.dl_src[i] ^ match.dl_src_mask[i]
+            match.dl_dst[i] = match.dl_dst[i] ^ match.dl_dst_mask[i]
+        match.nw_src = match.nw_src ^ match.nw_src_mask
+        match.nw_dst = match.nw_dst ^ match.nw_dst_mask
+
+    request = flow_msg_create(parent, pkt, ing_port=ing_port, 
+                              match=match,
+                              wildcards=wildcards, egr_port=egr_port,
+                              action_list=apply_action_list)
+
+    flow_msg_install(parent, request)
+
+    logging.debug("Send packet: " + str(ing_port) + " to " + str(egr_port))
+    parent.dataplane.send(ing_port, str(pkt))
+
+    if exp_pkt is None:
+        exp_pkt = pkt
+    receive_pkt_verify(parent, egr_port, exp_pkt)
+
+    if check_expire:
+        #@todo Not all HW supports both pkt and byte counters
+        flow_removed_verify(parent, request, pkt_count=1, byte_count=len(pkt))
+def flow_match_test(parent, port_map, match=None, wildcards=0,
+                    mask=None, dl_vlan=-1, pkt=None,
+                    exp_pkt=None, apply_action_list=None,
+                    check_expire=False,  max_test=0):
+    """
+    Run flow_match_test_port_pair on all port pairs
+
+    @param max_test If > 0 no more than this number of tests are executed.
+    @param parent Must implement controller, dataplane, assertTrue, assertEqual
+    and logger
+    @param pkt If not None, use this packet for ingress
+    @param match If not None, use this value in flow_mod
+    @param wildcards For flow match entry
+    @param mask DL/NW address bit masks as a dictionary. If set, it is tested
+    against the corresponding match fields with the opposite values
+    @param dl_vlan If not -1, and pkt is None, create a pkt w/ VLAN tag
+    @param exp_pkt If not None, use this as the expected output pkt; els use pkt
+    @param action_list Additional actions to add to flow mod
+    @param check_expire Check for flow expiration ofp.message
+    """
+    of_ports = port_map.keys()
+    of_ports.sort()
+    parent.assertTrue(len(of_ports) > 1, "Not enough ports for test")
+    test_count = 0
+
+    for ing_idx in range(len(of_ports)):
+        ingress_port = of_ports[ing_idx]
+        for egr_idx in range(len(of_ports)):
+            if egr_idx == ing_idx:
+                continue
+            egress_port = of_ports[egr_idx]
+            flow_match_test_port_pair(parent, ingress_port, egress_port, 
+                                      match=match, wildcards=wildcards,
+                                      dl_vlan=dl_vlan, mask=mask,
+                                      pkt=pkt, exp_pkt=exp_pkt,
+                                      apply_action_list=apply_action_list,
+                                      check_expire=check_expire)
+            test_count += 1
+            if (max_test > 0) and (test_count >= max_test):
+                logging.info("Ran " + str(test_count) + " tests; exiting")
+                return
+
+def flow_match_test_port_pair_vlan(parent, ing_port, egr_port, wildcards=0,
+                                   dl_vlan=ofp.OFPVID_NONE, dl_vlan_pcp=0,
+                                   dl_vlan_type=ETHERTYPE_VLAN,
+                                   dl_vlan_int=-1, dl_vlan_pcp_int=0,
+                                   vid_match=ofp.OFPVID_NONE, pcp_match=0,
+                                   exp_vid=-1, exp_pcp=0,
+                                   exp_vlan_type=ETHERTYPE_VLAN,
+                                   match_exp=True,
+                                   add_tag_exp=False,
+                                   exp_msg=ofp.OFPT_FLOW_REMOVED,
+                                   exp_msg_type=0, exp_msg_code=0,
+                                   pkt=None, exp_pkt=None,
+                                   action_list=None, check_expire=False):
+    """
+    Flow match test for various vlan matching patterns on single TCP packet
+
+    Run test with packet through switch from ing_port to egr_port
+    See flow_match_test_vlan for parameter descriptions
+    """
+    logging.info("Pkt match test: " + str(ing_port) + " to " + str(egr_port))
+    logging.debug("  WC: " + hex(wildcards) + " vlan: " + str(dl_vlan) +
+                    " expire: " + str(check_expire))
+    if pkt is None:
+        if dl_vlan >= 0 and dl_vlan != ofp.OFPVID_NONE:
+            if dl_vlan_int >= 0 and dl_vlan_int != ofp.OFPVID_NONE:
+                pkt = simple_tcp_packet(
+                        vlan_tags=[{'type': dl_vlan_type, 'vid': dl_vlan, 'pcp': dl_vlan_pcp},
+                                   {'vid': dl_vlan_int, 'pcp': dl_vlan_pcp_int}])
+            else:
+                pkt = simple_tcp_packet(
+                        vlan_tags=[{'type': dl_vlan_type, 'vid': dl_vlan, 'pcp': dl_vlan_pcp}])
+        else:
+            pkt = simple_tcp_packet()
+
+    if exp_pkt is None:
+        if exp_vid >= 0 and exp_vid != ofp.OFPVID_NONE:
+            if add_tag_exp:
+                if dl_vlan >= 0 and dl_vlan != ofp.OFPVID_NONE:
+                    if dl_vlan_int >= 0 and dl_vlan_int != ofp.OFPVID_NONE:
+                        exp_pkt = simple_tcp_packet(
+                                    vlan_tags=[{'type': exp_vlan_type, 'vid': exp_vid, 'pcp': exp_pcp},
+                                               {'type': dl_vlan_type, 'vid': dl_vlan, 'pcp': dl_vlan_pcp},
+                                               {'vid': dl_vlan_int, 'pcp': dl_vlan_pcp_int}])
+                    else:
+                        exp_pkt = simple_tcp_packet(
+                                    vlan_tags=[{'type': exp_vlan_type, 'vid': exp_vid, 'pcp': exp_pcp},
+                                               {'type': dl_vlan_type, 'vid': dl_vlan, 'pcp': dl_vlan_pcp}])
+                else:
+                    exp_pkt = simple_tcp_packet(
+                                vlan_tags=[{'type': exp_vlan_type, 'vid': exp_vid, 'pcp': exp_pcp}])
+            else:
+                if dl_vlan_int >= 0:
+                    exp_pkt = simple_tcp_packet(
+                                vlan_tags=[{'type': exp_vlan_type, 'vid': exp_vid, 'pcp': exp_pcp},
+                                           {'vid': dl_vlan_int, 'pcp': dl_vlan_pcp_int}])
+
+                else:
+                    exp_pkt = simple_tcp_packet(
+                                vlan_tags=[{'type': exp_vlan_type, 'vid': exp_vid, 'pcp': exp_pcp}])
+        else:
+            #subtract ofp.action
+            if dl_vlan_int >= 0:
+                exp_pkt = simple_tcp_packet(
+                            vlan_tags=[{'vid': dl_vlan_int, 'pcp': dl_vlan_pcp_int}])
+            else:
+                exp_pkt = simple_tcp_packet()
+
+    match = parse.packet_to_flow_match(pkt)
+    parent.assertTrue(match is not None, "Flow match from pkt failed")
+
+    match.dl_vlan = vid_match
+    match.dl_vlan_pcp = pcp_match
+    match.wildcards = wildcards
+
+    request = flow_msg_create(parent, pkt, ing_port=ing_port,
+                              wildcards=wildcards,
+                              match=match,
+                              egr_port=egr_port,
+                              action_list=action_list)
+
+    flow_msg_install(parent, request)
+
+    logging.debug("Send packet: " + str(ing_port) + " to " + str(egr_port))
+    logging.debug("Sent:" + str(pkt).encode('hex'))
+    parent.dataplane.send(ing_port, str(pkt))
+
+    if match_exp:
+        receive_pkt_verify(parent, egr_port, exp_pkt)
+        if check_expire:
+            #@todo Not all HW supports both pkt and byte counters
+            flow_removed_verify(parent, request, pkt_count=1, byte_count=len(pkt))
+    else:
+        if exp_msg is ofp.OFPT_FLOW_REMOVED:
+            if check_expire:
+                flow_removed_verify(parent, request, pkt_count=0, byte_count=0)
+        elif exp_msg is ofp.OFPT_ERROR:
+            error_verify(parent, exp_msg_type, exp_msg_code)
+        else:
+            parent.assertTrue(0, "Rcv: Unexpected ofp.message: " + str(exp_msg))
+
+        (_, rcv_pkt, _) = parent.dataplane.poll(timeout=1)
+        parent.assertFalse(rcv_pkt is not None, "Packet on dataplane")
+
+def flow_match_test_vlan(parent, port_map, wildcards=0,
+                         dl_vlan=ofp.OFPVID_NONE, dl_vlan_pcp=0, dl_vlan_type=ETHERTYPE_VLAN,
+                         dl_vlan_int=-1, dl_vlan_pcp_int=0,
+                         vid_match=ofp.OFPVID_NONE, pcp_match=0,
+                         exp_vid=-1, exp_pcp=0,
+                         exp_vlan_type=ETHERTYPE_VLAN,
+                         match_exp=True,
+                         add_tag_exp=False,
+                         exp_msg=ofp.OFPT_FLOW_REMOVED,
+                         exp_msg_type=0, exp_msg_code=0,
+                         pkt=None, exp_pkt=None,
+                         action_list=None,
+                         check_expire=False,
+                         max_test=0):
+    """
+    Run flow_match_test_port_pair on all port pairs
+
+    @param max_test If > 0 no more than this number of tests are executed.
+    @param parent Must implement controller, dataplane, assertTrue, assertEqual
+    and logger
+    @param wildcards For flow match entry
+    @param dl_vlan If not -1, and pkt is not None, create a pkt w/ VLAN tag
+    @param dl_vlan_pcp VLAN PCP associated with dl_vlan
+    @param dl_vlan_type VLAN ether type associated with dl_vlan
+    @param dl_vlan_int If not -1, create pkt w/ Inner Vlan tag
+    @param dl_vlan_pcp_int VLAN PCP associated with dl_vlan_2nd
+    @param vid_match Matching value for VLAN VID field
+    @param pcp_match Matching value for VLAN PCP field
+    @param exp_vid Expected VLAN VID value. If -1, no VLAN expected
+    @param exp_vlan_type Expected VLAN ether type
+    @param exp_pcp Expected VLAN PCP value
+    @param match_exp Set whether packet is expected to receive
+    @param add_tag_exp If True, expected_packet has an additional vlan tag,
+    If not, expected_packet's vlan tag is replaced as specified
+    @param exp_msg Expected ofp.message
+    @param exp_msg_type Expected ofp.message type associated with the ofp.message
+    @param exp_msg_code Expected ofp.message code associated with the msg_type
+    @param pkt If not None, use this packet for ingress
+    @param exp_pkt If not None, use this as the expected output pkt
+    @param action_list Additional actions to add to flow mod
+    @param check_expire Check for flow expiration ofp.message
+    """
+    of_ports = port_map.keys()
+    of_ports.sort()
+    parent.assertTrue(len(of_ports) > 1, "Not enough ports for test")
+    test_count = 0
+
+    for ing_idx in range(len(of_ports)):
+        ingress_port = of_ports[ing_idx]
+        for egr_idx in range(len(of_ports)):
+            if egr_idx == ing_idx:
+                continue
+            egress_port = of_ports[egr_idx]
+            flow_match_test_port_pair_vlan(parent, ingress_port, egress_port,
+                                           wildcards=wildcards,
+                                           dl_vlan=dl_vlan,
+                                           dl_vlan_pcp=dl_vlan_pcp,
+                                           dl_vlan_type=dl_vlan_type,
+                                           dl_vlan_int=dl_vlan_int,
+                                           dl_vlan_pcp_int=dl_vlan_pcp_int,
+                                           vid_match=vid_match,
+                                           pcp_match=pcp_match,
+                                           exp_vid=exp_vid,
+                                           exp_pcp=exp_pcp,
+                                           exp_vlan_type=exp_vlan_type,
+                                           exp_msg=exp_msg,
+                                           exp_msg_type=exp_msg_type,
+                                           exp_msg_code=exp_msg_code,
+                                           match_exp=match_exp,
+                                           add_tag_exp=add_tag_exp,
+                                           pkt=pkt, exp_pkt=exp_pkt,
+                                           action_list=action_list,
+                                           check_expire=check_expire)
+            test_count += 1
+            if (max_test > 0) and (test_count >= max_test):
+                logging.info("Ran " + str(test_count) + " tests; exiting")
+                return
+
+def test_param_get(config, key, default=None):
+    """
+    Return value passed via test-params if present
+
+    @param config The configuration structure for OFTest
+    @param key The lookup key
+    @param default Default value to use if not found
+
+    If the pair 'key=val' appeared in the string passed to --test-params
+    on the command line, return val (as interpreted by exec).  Otherwise
+    return default value.
+    """
+    try:
+        exec config["test_params"]
+    except:
+        return default
+
+    s = "val = " + str(key)
+    try:
+        val = None
+        exec s
+        return val
+    except:
+        return default
+
+def action_generate(parent, field_to_mod, mod_field_vals):
+    """
+    Create an ofp.action to modify the field indicated in field_to_mod
+
+    @param parent Must implement, assertTrue
+    @param field_to_mod The field to modify as a string name
+    @param mod_field_vals Hash of values to use for modified values
+    """
+
+    act = None
+
+    if field_to_mod in ['pktlen']:
+        return None
+
+    if field_to_mod == 'dl_dst':
+        act = ofp.action.set_dl_dst()
+        act.dl_addr = parse.parse_mac(mod_field_vals['dl_dst'])
+    elif field_to_mod == 'dl_src':
+        act = ofp.action.set_dl_src()
+        act.dl_addr = parse.parse_mac(mod_field_vals['dl_src'])
+    elif field_to_mod == 'vlan_tags':
+        if len(mod_field_vals['vlan_tags']):
+            act = ofp.action.pop_vlan()
+        else:
+            pass
+#    elif field_to_mod == 'dl_vlan_enable':
+#        if not mod_field_vals['dl_vlan_enable']: # Strip VLAN tag
+#            act = ofp.action.pop_vlan()
+#        # Add VLAN tag is handled by dl_vlan field
+#        # Will return None in this case
+#    elif field_to_mod == 'dl_vlan':
+#        act = ofp.action.set_vlan_vid()
+#        act.vlan_vid = mod_field_vals['dl_vlan']
+#    elif field_to_mod == 'dl_vlan_pcp':
+#        act = ofp.action.set_vlan_pcp()
+#        act.vlan_pcp = mod_field_vals['dl_vlan_pcp']
+    elif field_to_mod == 'ip_src':
+        act = ofp.action.set_nw_src()
+        act.nw_addr = parse.parse_ip(mod_field_vals['ip_src'])
+    elif field_to_mod == 'ip_dst':
+        act = ofp.action.set_nw_dst()
+        act.nw_addr = parse.parse_ip(mod_field_vals['ip_dst'])
+    elif field_to_mod == 'ip_tos':
+        act = ofp.action.set_nw_tos()
+        act.nw_tos = mod_field_vals['ip_tos']
+    elif field_to_mod == 'tcp_sport':
+        act = ofp.action.set_tp_src()
+        act.tp_port = mod_field_vals['tcp_sport']
+    elif field_to_mod == 'tcp_dport':
+        act = ofp.action.set_tp_dst()
+        act.tp_port = mod_field_vals['tcp_dport']
+    else:
+        parent.assertTrue(0, "Unknown field to modify: " + str(field_to_mod))
+
+    return act
+
+def pkt_action_setup(parent, start_field_vals={}, mod_field_vals={}, 
+                     mod_fields={}, check_test_params=False):
+    """
+    Set up the ingress and expected packet and ofp.action list for a test
+
+    @param parent Must implement, assertTrue, config hash and logger
+    @param start_field_values Field values to use for ingress packet (optional)
+    @param mod_field_values Field values to use for modified packet (optional)
+    @param mod_fields The list of fields to be modified by the switch in the test.
+    @params check_test_params If True, will check the parameters vid, add_vlan
+    and strip_vlan from the command line.
+
+    Returns a triple:  pkt-to-send, expected-pkt, ofp.action-list
+    """
+
+    new_actions = []
+
+
+    base_pkt_params = {}
+    base_pkt_params['dl_dst'] = '00:DE:F0:12:34:56'
+    base_pkt_params['dl_src'] = '00:23:45:67:89:AB'
+#    base_pkt_params['dl_vlan_enable'] = False
+#    base_pkt_params['dl_vlan'] = 2
+#    base_pkt_params['dl_vlan_pcp'] = 0
+    base_pkt_params['ip_src'] = '192.168.0.1'
+    base_pkt_params['ip_dst'] = '192.168.0.2'
+    base_pkt_params['ip_tos'] = 0
+    base_pkt_params['tcp_sport'] = 1234
+    base_pkt_params['tcp_dport'] = 80
+    for keyname in start_field_vals.keys():
+        base_pkt_params[keyname] = start_field_vals[keyname]
+
+    mod_pkt_params = {}
+    mod_pkt_params['dl_dst'] = '00:21:0F:ED:CB:A9'
+    mod_pkt_params['dl_src'] = '00:ED:CB:A9:87:65'
+#    mod_pkt_params['dl_vlan_enable'] = False
+#    mod_pkt_params['dl_vlan'] = 3
+#    mod_pkt_params['dl_vlan_pcp'] = 7
+    mod_pkt_params['ip_src'] = '10.20.30.40'
+    mod_pkt_params['ip_dst'] = '50.60.70.80'
+    mod_pkt_params['ip_tos'] = 0xf0
+    mod_pkt_params['tcp_sport'] = 4321
+    mod_pkt_params['tcp_dport'] = 8765
+    for keyname in mod_field_vals.keys():
+        mod_pkt_params[keyname] = mod_field_vals[keyname]
+
+    # Check for test param modifications
+    strip = False
+    if check_test_params:
+        add_vlan = test_param_get(parent.config, 'add_vlan')
+        strip_vlan = test_param_get(parent.config, 'strip_vlan')
+        vid = test_param_get(parent.config, 'vid')
+
+        if add_vlan and strip_vlan:
+            parent.assertTrue(0, "Add and strip VLAN both specified")
+
+        if vid:
+            base_pkt_params['dl_vlan_enable'] = True
+            base_pkt_params['dl_vlan'] = vid
+            if 'dl_vlan' in mod_fields:
+                mod_pkt_params['dl_vlan'] = vid + 1
+
+        if add_vlan:
+            base_pkt_params['dl_vlan_enable'] = False
+            mod_pkt_params['dl_vlan_enable'] = True
+            mod_pkt_params['pktlen'] = base_pkt_params['pktlen'] + 4
+            mod_fields.append('pktlen')
+            mod_fields.append('dl_vlan_enable')
+            if 'dl_vlan' not in mod_fields:
+                mod_fields.append('dl_vlan')
+        elif strip_vlan:
+            base_pkt_params['dl_vlan_enable'] = True
+            mod_pkt_params['dl_vlan_enable'] = False
+            mod_pkt_params['pktlen'] = base_pkt_params['pktlen'] - 4
+            mod_fields.append('dl_vlan_enable')
+            mod_fields.append('pktlen')
+
+    # Build the ingress packet
+    ingress_pkt = simple_tcp_packet(**base_pkt_params)
+
+    # Build the expected packet, modifying the indicated fields
+    for item in mod_fields:
+        base_pkt_params[item] = mod_pkt_params[item]
+        act = action_generate(parent, item, mod_pkt_params)
+        if act:
+            new_actions.append(act)
+
+    expected_pkt = simple_tcp_packet(**base_pkt_params)
+
+    return (ingress_pkt, expected_pkt, new_actions)
+        
+def wildcard_all_set(match):
+    match.wildcards = ofp.OFPFW_ALL
+    match.nw_dst_mask = 0xffffffff
+    match.nw_src_mask = 0xffffffff
+    match.dl_dst_mask = [0xff, 0xff, 0xff, 0xff, 0xff, 0xff]
+    match.dl_src_mask = [0xff, 0xff, 0xff, 0xff, 0xff, 0xff]
+    match.metadata_mask = 0xffffffffffffffff
+
+def skip_message_emit(parent, s):
+    """
+    Print out a 'skipped' ofp.message to stderr
+
+    @param s The string to print out to the log file
+    @param parent Must implement config and logger objects
+    """
+    global skipped_test_count
+
+    skipped_test_count += 1
+    logging.info("Skipping: " + s)
+    if parent.config["debug"] < logging.WARNING:
+        sys.stderr.write("(skipped) ")
+    else:
+        sys.stderr.write("(S)")
+
+def do_echo_request_reply_test(test,controller):
+        request = ofp.message.echo_request()
+        response, _ = controller.transact(request)
+        test.assertEqual(response.type, ofp.OFPT_ECHO_REPLY,
+                         'response is not echo_reply')
+        test.assertEqual(request.xid, response.xid,
+                         'response xid != request xid')
+        test.assertEqual(len(response.data), 0, 'response data non-empty')
+
+def match_all_generate():
+    match = ofp.ofp_match()
+    return match
+
+def simple_tcp_packet_w_mpls(
+                      dl_dst='00:01:02:03:04:05',
+                      dl_src='00:06:07:08:09:0a',
+                      mpls_type=0x8847,
+                      mpls_label=-1,
+                      mpls_tc=0,
+                      mpls_ttl=64,
+                      mpls_label_int=-1,
+                      mpls_tc_int=0,
+                      mpls_ttl_int=32,
+                      mpls_label_ext=-1,
+                      mpls_tc_ext=0,
+                      mpls_ttl_ext=128,
+                      ip_src='192.168.0.1',
+                      ip_dst='192.168.0.2',
+                      ip_tos=0,
+                      ip_ttl=192,
+                      tcp_sport=1234,
+                      tcp_dport=80
+                      ):
+    """
+    Return a simple dataplane TCP packet w/wo MPLS tags
+
+    Supports a few parameters:
+    @param len Length of packet in bytes w/o CRC
+    @param dl_dst Destinatino MAC
+    @param dl_src Source MAC
+    @param mpls_type MPLS type as ether type
+    @param mpls_label MPLS LABEL if not -1
+    @param mpls_tc MPLS TC
+    @param mpls_ttl MPLS TTL
+    @param mpls_label_int Inner MPLS LABEL if not -1. The shim will be added
+    inside of mpls_label shim.
+    @param mpls_tc_int Inner MPLS TC
+    @param mpls_ttl_int Inner MPLS TTL
+    @param mpls_label_ext External MPLS LABEL if not -1. The shim will be
+    added outside of mpls_label shim
+    @param mpls_tc_ext External MPLS TC
+    @param mpls_ttl_ext External MPLS TTL
+    @param ip_src IP source
+    @param ip_dst IP destination
+    @param ip_tos IP ToS
+    @param tcp_dport TCP destination port
+    @param ip_sport TCP source port
+
+    Generates a simple MPLS/IP/TCP request.  Users
+    shouldn't assume anything about this packet other than that
+    it is a valid ethernet/IP/TCP frame.
+    """
+    
+    mpls_tags = []
+    
+    if mpls_label_ext >= 0:
+        mpls_tags.append({'type': mpls_type, 'label': mpls_label_ext, 'tc': mpls_tc_ext, 'ttl': mpls_ttl_ext})
+        
+    if mpls_label >= 0:
+        mpls_tags.append({'type': mpls_type, 'label': mpls_label, 'tc': mpls_tc, 'ttl': mpls_ttl})
+        
+    if mpls_label_int >= 0:
+        mpls_tags.append({'type': mpls_type, 'label': mpls_label_int, 'tc': mpls_tc_int, 'ttl': mpls_ttl_int})
+    
+    pkt = simple_tcp_packet(dl_dst=dl_dst,
+                            dl_src=dl_src,
+                            mpls_tags=mpls_tags,
+                            ip_src=ip_src,
+                            ip_dst=ip_dst,
+                            ip_tos=ip_tos,  
+                            ip_ttl=ip_ttl,
+                            tcp_sport=tcp_sport,
+                            tcp_dport=tcp_dport)
+    return pkt
+    
+def flow_match_test_port_pair_mpls(parent, ing_port, egr_port, wildcards=0,
+                                   mpls_type=0x8847,
+                                   mpls_label=-1, mpls_tc=0,mpls_ttl=64,
+                                   mpls_label_int=-1, mpls_tc_int=0,
+                                   mpls_ttl_int=32,
+                                   ip_ttl=192,
+                                   exp_mpls_type=0x8847,
+                                   exp_mpls_label=-1, exp_mpls_tc=0,
+                                   exp_mpls_ttl=64,
+                                   exp_mpls_ttl_int=32,
+                                   exp_ip_ttl=192,
+                                   label_match=0, tc_match=0,
+                                   dl_type_match=ETHERTYPE_MPLS,
+                                   match_exp=True,
+                                   add_tag_exp=False,
+                                   exp_msg=ofp.OFPT_FLOW_REMOVED,
+                                   exp_msg_type=0, exp_msg_code=0,
+                                   pkt=None,
+                                   exp_pkt=None, action_list=None,
+                                   check_expire=False):
+    """
+    Flow match test on single packet w/ MPLS tags
+
+    Run test with packet through switch from ing_port to egr_port
+    See flow_match_test for parameter descriptions
+    """
+    logging.info("Pkt match test: " + str(ing_port) + " to " + str(egr_port))
+    logging.debug("  WC: " + hex(wildcards) + " MPLS: " +
+                    str(mpls_label) + " expire: " + str(check_expire))
+
+    if pkt is None:
+
+        pkt = simple_tcp_packet_w_mpls(mpls_type=mpls_type,
+                                       mpls_label=mpls_label,
+                                       mpls_tc=mpls_tc,
+                                       mpls_ttl=mpls_ttl,
+                                       mpls_label_int=mpls_label_int,
+                                       mpls_tc_int=mpls_tc_int,
+                                       mpls_ttl_int=mpls_ttl_int,
+                                       ip_ttl=ip_ttl)
+
+    if exp_pkt is None:
+        if add_tag_exp:
+            exp_pkt = simple_tcp_packet_w_mpls(
+                                           mpls_type=exp_mpls_type,
+                                           mpls_label_ext=exp_mpls_label,
+                                           mpls_tc_ext=exp_mpls_tc,
+                                           mpls_ttl_ext=exp_mpls_ttl,
+                                           mpls_label=mpls_label,
+                                           mpls_tc=mpls_tc,
+                                           mpls_ttl=mpls_ttl,
+                                           mpls_label_int=mpls_label_int,
+                                           mpls_tc_int=mpls_tc_int,
+                                           mpls_ttl_int=exp_mpls_ttl_int,
+                                           ip_ttl=exp_ip_ttl)
+        else:
+            if (exp_mpls_label < 0) and (mpls_label_int >= 0):
+                exp_pkt = simple_tcp_packet_w_mpls(
+                                           mpls_type=mpls_type,
+                                           mpls_label=mpls_label_int,
+                                           mpls_tc=mpls_tc_int,
+                                           mpls_ttl=exp_mpls_ttl_int,
+                                           ip_ttl=exp_ip_ttl)
+            else:
+                exp_pkt = simple_tcp_packet_w_mpls(
+                                           mpls_type=exp_mpls_type,
+                                           mpls_label=exp_mpls_label,
+                                           mpls_tc=exp_mpls_tc,
+                                           mpls_ttl=exp_mpls_ttl,
+                                           mpls_label_int=mpls_label_int,
+                                           mpls_tc_int=mpls_tc_int,
+                                           mpls_ttl_int=exp_mpls_ttl_int,
+                                           ip_ttl=exp_ip_ttl)
+    wildcards = (ofp.OFPFW_ALL & ~(ofp.OFPFW_DL_TYPE | ofp.OFPFW_MPLS_LABEL | ofp.OFPFW_MPLS_TC)) | wildcards
+
+    match = parse.packet_to_flow_match(pkt)
+    parent.assertTrue(match is not None, "Flow match from pkt failed")
+
+    match.mpls_label = label_match
+    match.mpls_tc = tc_match
+    match.wildcards = wildcards
+
+    match.dl_type = dl_type_match
+    match.nw_tos = 0
+    match.nw_proto = 0
+    match.nw_src = 0
+    match.nw_src_mask = 0xFFFFFFFF
+    match.nw_dst = 0
+    match.nw_dst_mask = 0xFFFFFFFF
+    match.tp_src = 0
+    match.tp_dst = 0
+
+    request = flow_msg_create(parent, pkt, ing_port=ing_port,
+                              wildcards=wildcards,
+                              match=match,
+                              egr_port=egr_port,
+                              action_list=action_list)
+
+    flow_msg_install(parent, request)
+
+    logging.debug("Send packet: " + str(ing_port) + " to " + str(egr_port))
+    #logging.debug(str(pkt).encode("hex"))
+    parent.dataplane.send(ing_port, str(pkt))
+
+    if match_exp:
+        receive_pkt_verify(parent, egr_port, exp_pkt)
+        if check_expire:
+            #@todo Not all HW supports both pkt and byte counters
+            flow_removed_verify(parent, request, pkt_count=1, byte_count=len(pkt))
+    else:
+        if exp_msg == ofp.OFPT_FLOW_REMOVED:
+            if check_expire:
+                flow_removed_verify(parent, request, pkt_count=0, byte_count=0)
+        elif exp_msg == ofp.OFPT_ERROR:
+            error_verify(parent, exp_msg_type, exp_msg_code)
+        else:
+            parent.assertTrue(0, "Rcv: Unexpected ofp.message: " + str(exp_msg))
+        (_, rcv_pkt, _) = parent.dataplane.poll(timeout=1)
+        parent.assertFalse(rcv_pkt is not None, "Packet on dataplane")
+
+def flow_match_test_mpls(parent, port_map, wildcards=0,
+                         mpls_type=0x8847,
+                         mpls_label=-1, mpls_tc=0, mpls_ttl=64,
+                         mpls_label_int=-1, mpls_tc_int=0, mpls_ttl_int=32,
+                         ip_ttl = 192,
+                         label_match=0, tc_match=0,
+                         dl_type_match=ETHERTYPE_MPLS,
+                         exp_mpls_type=0x8847,
+                         exp_mpls_label=-1, exp_mpls_tc=0, exp_mpls_ttl=64,
+                         exp_mpls_ttl_int=32,
+                         exp_ip_ttl=192,
+                         match_exp=True,
+                         add_tag_exp=False,
+                         exp_msg=ofp.OFPT_FLOW_REMOVED,
+                         exp_msg_type=0, exp_msg_code=0,
+                         pkt=None,
+                         exp_pkt=None, action_list=None, check_expire=False,
+                         max_test=0):
+    """
+    Run flow_match_test_port_pair on all port pairs
+
+    @param max_test If > 0 no more than this number of tests are executed.
+    @param parent Must implement controller, dataplane, assertTrue, assertEqual
+    and logger
+    @param wildcards For flow match entry
+    @param mpls_type MPLS type
+    @param mpls_label If not -1 create a pkt w/ MPLS tag
+    @param mpls_tc MPLS TC associated with MPLS label
+    @param mpls_ttl MPLS TTL associated with MPLS label
+    @param mpls_label_int If not -1 create a pkt w/ Inner MPLS tag
+    @param mpls_tc_int MPLS TC associated with Inner MPLS label
+    @param mpls_ttl_int MPLS TTL associated with Inner MPLS label
+    @param ip_ttl IP TTL
+    @param label_match Matching value for MPLS LABEL field
+    @param tc_match Matching value for MPLS TC field
+    @param exp_mpls_label Expected MPLS LABEL value. If -1, no MPLS expected
+    @param exp_mpls_tc Expected MPLS TC value
+    @param exp_mpls_ttl Expected MPLS TTL value
+    @param exp_mpls_ttl_int Expected Inner MPLS TTL value
+    @param ip_ttl Expected IP TTL
+    @param match_exp Set whether packet is expected to receive
+    @param add_tag_exp If True, expected_packet has an additional MPLS shim,
+    If not expected_packet's MPLS shim is replaced as specified
+    @param exp_msg Expected ofp.message
+    @param exp_msg_type Expected ofp.message type associated with the ofp.message
+    @param exp_msg_code Expected ofp.message code associated with the msg_type
+    @param pkt If not None, use this packet for ingress
+    @param exp_pkt If not None, use this as the expected output pkt; els use pkt
+    @param action_list Additional actions to add to flow mod
+    @param check_expire Check for flow expiration ofp.message
+    """
+    of_ports = port_map.keys()
+    of_ports.sort()
+    parent.assertTrue(len(of_ports) > 1, "Not enough ports for test")
+    test_count = 0
+
+    for ing_idx in range(len(of_ports)):
+        ingress_port = of_ports[ing_idx]
+        for egr_idx in range(len(of_ports)):
+            if egr_idx == ing_idx:
+                continue
+            egress_port = of_ports[egr_idx]
+            flow_match_test_port_pair_mpls(parent, ingress_port, egress_port,
+                                      wildcards=wildcards,
+                                      mpls_type=mpls_type,
+                                      mpls_label=mpls_label,
+                                      mpls_tc=mpls_tc,
+                                      mpls_ttl=mpls_ttl,
+                                      mpls_label_int=mpls_label_int,
+                                      mpls_tc_int=mpls_tc_int,
+                                      mpls_ttl_int=mpls_ttl_int,
+                                      ip_ttl=ip_ttl,
+                                      label_match=label_match,
+                                      tc_match=tc_match,
+                                      dl_type_match=dl_type_match,
+                                      exp_mpls_type=exp_mpls_type,
+                                      exp_mpls_label=exp_mpls_label,
+                                      exp_mpls_tc=exp_mpls_tc,
+                                      exp_mpls_ttl=exp_mpls_ttl,
+                                      exp_mpls_ttl_int=exp_mpls_ttl_int,
+                                      exp_ip_ttl=exp_ip_ttl,
+                                      match_exp=match_exp,
+                                      exp_msg=exp_msg,
+                                      exp_msg_type=exp_msg_type,
+                                      exp_msg_code=exp_msg_code,
+                                      add_tag_exp=add_tag_exp,
+                                      pkt=pkt, exp_pkt=exp_pkt,
+                                      action_list=action_list,
+                                      check_expire=check_expire)
+            test_count += 1
+            if (max_test > 0) and (test_count >= max_test):
+                logging.info("Ran " + str(test_count) + " tests; exiting")
+                return
+
+def flow_stats_get(parent, match_fields = None):
+    """ Get the flow_stats from the switch
+    Test the response to make sure it's really a flow_stats object
+    """
+    request = ofp.message.flow_stats_request()
+    request.out_port = ofp.OFPP_ANY
+    request.out_group = ofp.OFPG_ANY
+    request.table_id = 0xff
+    if match_fields != None:
+        request.match_fields = match_fields
+    response, _ = parent.controller.transact(request, timeout=2)
+    parent.assertTrue(response is not None, "Did not get response")
+    parent.assertTrue(isinstance(response,ofp.message.flow_stats_reply),
+                      "Expected a flow_stats_reply, but didn't get it")
+    return response
diff --git a/Fabric/Utilities/src/python/oftest/ofutils.py b/Fabric/Utilities/src/python/oftest/ofutils.py
new file mode 100644
index 0000000..7e6044d
--- /dev/null
+++ b/Fabric/Utilities/src/python/oftest/ofutils.py
@@ -0,0 +1,80 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+
+"""
+Utilities for the OpenFlow test framework
+"""
+
+import random
+import time
+import os
+import fcntl
+import logging
+
+default_timeout = None # set by oft
+default_negative_timeout = None # set by oft
+
+def gen_xid():
+    return random.randrange(1,0xffffffff)
+
+"""
+Wait on a condition variable until the given function returns non-None or a timeout expires.
+The condition variable must already be acquired.
+The timeout value -1 means use the default timeout.
+There is deliberately no support for an infinite timeout.
+"""
+def timed_wait(cv, fn, timeout=-1):
+    if timeout == -1:
+        timeout = default_timeout
+
+    end_time = time.time() + timeout
+    while True:
+        val = fn()
+        if val != None:
+            return val
+
+        remaining_time = end_time - time.time()
+        cv.wait(remaining_time)
+
+        if time.time() > end_time:
+            return None
+
+class EventDescriptor():
+    """
+    Similar to a condition variable, but can be passed to select().
+    Only supports one waiter.
+    """
+
+    def __init__(self):
+        self.pipe_rd, self.pipe_wr = os.pipe()
+        fcntl.fcntl(self.pipe_wr, fcntl.F_SETFL, os.O_NONBLOCK)
+
+    def __del__(self):
+        os.close(self.pipe_rd)
+        os.close(self.pipe_wr)
+
+    def notify(self):
+        try:
+            os.write(self.pipe_wr, "x")
+        except OSError as e:
+            logging.warn("Failed to notify EventDescriptor: %s", e)
+
+    def wait(self):
+        os.read(self.pipe_rd, 1)
+
+    def fileno(self):
+        return self.pipe_rd
diff --git a/Fabric/Utilities/src/python/oftest/packet.py b/Fabric/Utilities/src/python/oftest/packet.py
new file mode 100755
index 0000000..fa887bc
--- /dev/null
+++ b/Fabric/Utilities/src/python/oftest/packet.py
@@ -0,0 +1,82 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Distributed under the OpenFlow Software License (see LICENSE)
+# Copyright (c) 2010 The Board of Trustees of The Leland Stanford Junior University
+# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
+"""
+Wrap scapy to satisfy pylint
+"""
+from oftest import config
+import sys
+
+try:
+    import scapy.config
+    import scapy.route
+    import scapy.layers.l2
+    import scapy.layers.inet
+    if not config["disable_ipv6"]:
+        import scapy.route6
+        import scapy.layers.inet6
+except ImportError:
+    sys.exit("Need to install scapy for packet parsing")
+
+Ether = scapy.layers.l2.Ether
+LLC = scapy.layers.l2.LLC
+SNAP = scapy.layers.l2.SNAP
+Dot1Q = scapy.layers.l2.Dot1Q
+IP = scapy.layers.inet.IP
+IPOption = scapy.layers.inet.IPOption
+ARP = scapy.layers.inet.ARP
+TCP = scapy.layers.inet.TCP
+UDP = scapy.layers.inet.UDP
+ICMP = scapy.layers.inet.ICMP
+
+
+from scapy.fields import *
+from scapy.packet import *
+
+class ThreeBytesField(X3BytesField, ByteField):
+    def i2repr(self, pkt, x):
+        return ByteField.i2repr(self, pkt, x)
+
+class VXLAN(Packet):
+    name = "VXLAN"
+    fields_desc = [ FlagsField("flags", 0x08, 8, ['R', 'R', 'R', 'I', 'R', 'R', 'R', 'R']),
+                    X3BytesField("reserved1", 0x000000),
+                    ThreeBytesField("vni", 0),
+                    XByteField("reserved2", 0x00)]
+
+    def mysummary(self):
+        return self.sprintf("VXLAN (vni=%VXLAN.vni%)")
+
+bind_layers(UDP, VXLAN, dport=4789)
+bind_layers(VXLAN, Ether)
+
+
+class MPLS(Packet): 
+   name = "MPLS" 
+   fields_desc =  [ BitField("label", 3, 20), 
+                    BitField("cos", 0, 3), 
+                    BitField("s", 1, 1), 
+                    ByteField("ttl", 0)  ] 
+
+bind_layers(Ether, MPLS, type=0x8847)
+
+if not config["disable_ipv6"]:
+    IPv6 = scapy.layers.inet6.IPv6
+    ICMPv6Unknown = scapy.layers.inet6.ICMPv6Unknown
+    ICMPv6EchoRequest = scapy.layers.inet6.ICMPv6EchoRequest
diff --git a/Fabric/Utilities/src/python/oftest/parse.py b/Fabric/Utilities/src/python/oftest/parse.py
new file mode 100644
index 0000000..1f94c45
--- /dev/null
+++ b/Fabric/Utilities/src/python/oftest/parse.py
@@ -0,0 +1,301 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+"""
+Utility parsing functions
+"""
+
+import sys
+import socket
+import packet as scapy
+
+def parse_mac(mac_str):
+    """
+    Parse a MAC address
+
+    Parse a MAC address ':' separated string of hex digits to an
+    array of integer values.  '00:d0:05:5d:24:00' => [0, 208, 5, 93, 36, 0]
+    @param mac_str The string to convert
+    @return Array of 6 integer values
+    """
+    return map(lambda val: int(val, 16), mac_str.split(":"))
+
+def parse_ip(ip_str):
+    """
+    Parse an IP address
+
+    Parse an IP address '.' separated string of decimal digits to an
+    host ordered integer.  '172.24.74.77' => 
+    @param ip_str The string to convert
+    @return Integer value
+    """
+    array = map(lambda val: int(val), ip_str.split("."))
+    val = 0
+    for a in array:
+        val <<= 8
+        val += a
+    return val
+
+def parse_ipv6(ip_str):
+    """
+    Parse an IPv6 address
+
+    Parse a textual IPv6 address and return a 16 byte binary string.
+    """
+    return socket.inet_pton(socket.AF_INET6, ip_str)
+
+def packet_type_classify(ether):
+    try:
+        dot1q = ether[scapy.Dot1Q]
+    except:
+        dot1q = None
+
+    try:
+        ip = ether[scapy.IP]
+    except:
+        ip = None
+
+    try:
+        tcp = ether[scapy.TCP]
+    except:
+        tcp = None
+
+    try:
+        udp = ether[scapy.UDP]
+    except:
+        udp = None
+
+    try:
+        icmp = ether[scapy.ICMP]
+    except:
+        icmp = None
+
+    try:
+        arp = ether[scapy.ARP]
+    except:
+        arp = None
+    return (dot1q, ip, tcp, udp, icmp, arp)
+
+def packet_to_flow_match(packet):
+    """
+    Create a flow match that matches packet with the given wildcards
+
+    @param packet The packet to use as a flow template
+    @return An loxi.of10.match object
+
+    @todo check min length of packet
+    """
+    import ofp
+    if ofp.OFP_VERSION == 1:
+        return packet_to_flow_match_v1(packet)
+    elif ofp.OFP_VERSION == 3:
+        return packet_to_flow_match_v3(packet)
+    elif ofp.OFP_VERSION == 4:
+        return packet_to_flow_match_v4(packet)
+    elif ofp.OFP_VERSION == 5:
+        return packet_to_flow_match_v5(packet)
+    else:
+        raise NotImplementedError()
+
+def packet_to_flow_match_v1(packet):
+    """
+    OpenFlow 1.0 implementation of packet_to_flow_match
+    """
+    import loxi.of10 as ofp
+
+    if type(packet) == type(""):
+        ether = scapy.Ether(packet)
+    else:
+        ether = packet
+
+    # For now, assume ether IP packet and ignore wildcards
+    try:
+        (dot1q, ip, tcp, udp, icmp, arp) = packet_type_classify(ether)
+    except:
+        raise ValueError("could not classify packet")
+
+    match = ofp.match()
+    match.wildcards = ofp.OFPFW_ALL
+    #@todo Check if packet is other than L2 format
+    match.eth_dst = parse_mac(ether.dst)
+    match.wildcards &= ~ofp.OFPFW_DL_DST
+    match.eth_src = parse_mac(ether.src)
+    match.wildcards &= ~ofp.OFPFW_DL_SRC
+    match.eth_type = ether.type
+    match.wildcards &= ~ofp.OFPFW_DL_TYPE
+
+    if dot1q:
+        match.vlan_vid = dot1q.vlan
+        match.vlan_pcp = dot1q.prio
+        match.eth_type = dot1q.type
+    else:
+        match.vlan_vid = ofp.OFP_VLAN_NONE
+        match.vlan_pcp = 0
+    match.wildcards &= ~ofp.OFPFW_DL_VLAN
+    match.wildcards &= ~ofp.OFPFW_DL_VLAN_PCP
+
+    if ip:
+        match.ipv4_src = parse_ip(ip.src)
+        match.wildcards &= ~ofp.OFPFW_NW_SRC_MASK
+        match.ipv4_dst = parse_ip(ip.dst)
+        match.wildcards &= ~ofp.OFPFW_NW_DST_MASK
+        match.ip_dscp = ip.tos
+        match.wildcards &= ~ofp.OFPFW_NW_TOS
+
+    if tcp:
+        match.ip_proto = 6
+        match.wildcards &= ~ofp.OFPFW_NW_PROTO
+    elif not tcp and udp:
+        tcp = udp
+        match.ip_proto = 17
+        match.wildcards &= ~ofp.OFPFW_NW_PROTO
+
+    if tcp:
+        match.tcp_src = tcp.sport
+        match.wildcards &= ~ofp.OFPFW_TP_SRC
+        match.tcp_dst = tcp.dport
+        match.wildcards &= ~ofp.OFPFW_TP_DST
+
+    if icmp:
+        match.ip_proto = 1
+        match.tcp_src = icmp.type
+        match.tcp_dst = icmp.code
+        match.wildcards &= ~ofp.OFPFW_NW_PROTO
+
+    if arp:
+        match.ip_proto = arp.op
+        match.wildcards &= ~ofp.OFPFW_NW_PROTO
+        match.ipv4_src = parse_ip(arp.psrc)
+        match.wildcards &= ~ofp.OFPFW_NW_SRC_MASK
+        match.ipv4_dst = parse_ip(arp.pdst)
+        match.wildcards &= ~ofp.OFPFW_NW_DST_MASK
+
+    return match
+
+def packet_to_flow_match_v3(packet):
+    """
+    OpenFlow 1.2 implementation of packet_to_flow_match
+    """
+    import loxi.of12 as ofp
+    return packet_to_flow_match_oxm(packet, ofp)
+
+def packet_to_flow_match_v4(packet):
+    """
+    OpenFlow 1.3 implementation of packet_to_flow_match
+    """
+    import loxi.of13 as ofp
+    return packet_to_flow_match_oxm(packet, ofp)
+
+def packet_to_flow_match_v5(packet):
+    """
+    OpenFlow 1.3 implementation of packet_to_flow_match
+    """
+    import loxi.of14 as ofp
+    return packet_to_flow_match_oxm(packet, ofp)
+
+def packet_to_flow_match_oxm(packet, ofp):
+    def parse_ether_layer(layer, match):
+        assert(type(layer) == scapy.Ether)
+        match.oxm_list.append(ofp.oxm.eth_dst(parse_mac(layer.dst)))
+        match.oxm_list.append(ofp.oxm.eth_src(parse_mac(layer.src)))
+
+        if type(layer.payload) == scapy.Dot1Q:
+            layer = layer.payload
+            match.oxm_list.append(ofp.oxm.eth_type(layer.type))
+            match.oxm_list.append(ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT|layer.vlan))
+            match.oxm_list.append(ofp.oxm.vlan_pcp(layer.prio))
+        else:
+            match.oxm_list.append(ofp.oxm.eth_type(layer.type))
+            match.oxm_list.append(ofp.oxm.vlan_vid(ofp.OFP_VLAN_NONE))
+
+        if type(layer.payload) == scapy.IP:
+            parse_ipv4_layer(layer.payload, match)
+        elif type(layer.payload) == scapy.IPv6:
+            parse_ipv6_layer(layer.payload, match)
+        elif type(layer.payload) == scapy.ARP:
+            parse_arp_layer(layer.payload, match)
+        # TODO MPLS
+
+    def parse_ipv4_layer(layer, match):
+        assert(type(layer) == scapy.IP)
+        match.oxm_list.append(ofp.oxm.ip_proto(layer.proto))
+        match.oxm_list.append(ofp.oxm.ip_dscp(layer.tos >> 2))
+        match.oxm_list.append(ofp.oxm.ip_ecn(layer.tos & 3))
+        match.oxm_list.append(ofp.oxm.ipv4_src(parse_ip(layer.src)))
+        match.oxm_list.append(ofp.oxm.ipv4_dst(parse_ip(layer.dst)))
+
+        if type(layer.payload) == scapy.TCP:
+            parse_tcp_layer(layer.payload, match)
+        elif type(layer.payload) == scapy.UDP:
+            parse_udp_layer(layer.payload, match)
+        elif type(layer.payload) == scapy.ICMP:
+            parse_icmpv4_layer(layer.payload, match)
+        # TODO SCTP
+
+    def parse_tcp_layer(layer, match):
+        assert(type(layer) == scapy.TCP)
+        match.oxm_list.append(ofp.oxm.tcp_src(layer.sport))
+        match.oxm_list.append(ofp.oxm.tcp_dst(layer.dport))
+
+    def parse_udp_layer(layer, match):
+        assert(type(layer) == scapy.UDP)
+        match.oxm_list.append(ofp.oxm.udp_src(layer.sport))
+        match.oxm_list.append(ofp.oxm.udp_dst(layer.dport))
+
+    def parse_icmpv4_layer(layer, match):
+        assert(type(layer) == scapy.ICMP)
+        match.oxm_list.append(ofp.oxm.icmpv4_type(layer.type))
+        match.oxm_list.append(ofp.oxm.icmpv4_code(layer.code))
+
+    def parse_arp_layer(layer, match):
+        assert(type(layer) == scapy.ARP)
+        match.oxm_list.append(ofp.oxm.arp_op(layer.op))
+        match.oxm_list.append(ofp.oxm.arp_spa(parse_ip(layer.psrc)))
+        match.oxm_list.append(ofp.oxm.arp_tpa(parse_ip(layer.pdst)))
+        match.oxm_list.append(ofp.oxm.arp_sha(parse_mac(layer.hwsrc)))
+        match.oxm_list.append(ofp.oxm.arp_tha(parse_mac(layer.hwdst)))
+
+    def parse_ipv6_layer(layer, match):
+        assert(type(layer) == scapy.IPv6)
+        # TODO handle chained headers
+        match.oxm_list.append(ofp.oxm.ip_proto(layer.nh))
+        match.oxm_list.append(ofp.oxm.ip_dscp(layer.tc >> 2))
+        match.oxm_list.append(ofp.oxm.ip_ecn(layer.tc & 3))
+        match.oxm_list.append(ofp.oxm.ipv6_src(parse_ipv6(layer.src)))
+        match.oxm_list.append(ofp.oxm.ipv6_dst(parse_ipv6(layer.dst)))
+        match.oxm_list.append(ofp.oxm.ipv6_flabel(layer.fl))
+
+        if type(layer.payload) == scapy.TCP:
+            parse_tcp_layer(layer.payload, match)
+        elif type(layer.payload) == scapy.UDP:
+            parse_udp_layer(layer.payload, match)
+        elif layer.nh == 0x3a:
+            parse_icmpv6_layer(layer.payload, match)
+        # TODO ND
+        # TODO SCTP
+
+    def parse_icmpv6_layer(layer, match):
+        match.oxm_list.append(ofp.oxm.icmpv6_type(layer.type))
+        match.oxm_list.append(ofp.oxm.icmpv6_code(layer.code))
+
+    if type(packet) == type(""):
+        ether = scapy.Ether(packet)
+    else:
+        ether = packet
+
+    match = ofp.match()
+    parse_ether_layer(packet, match)
+    return match
diff --git a/Fabric/Utilities/src/python/oftest/pcap_writer.py b/Fabric/Utilities/src/python/oftest/pcap_writer.py
new file mode 100644
index 0000000..b405033
--- /dev/null
+++ b/Fabric/Utilities/src/python/oftest/pcap_writer.py
@@ -0,0 +1,77 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+"""
+Pcap file writer
+"""
+
+import struct
+
+PcapHeader = struct.Struct("<LHHLLLL")
+PcapPktHeader = struct.Struct("<LLLL")
+PPIPktHeader = struct.Struct("<BBHL")
+PPIAggregateField = struct.Struct("<HHL")
+
+class PcapWriter(object):
+    def __init__(self, filename):
+        """
+        Open a pcap file
+        """
+        self.stream = file(filename, 'w')
+
+        self.stream.write(PcapHeader.pack(
+            0xa1b2c3d4, # magic
+            2, # major
+            4, # minor
+            0, # timezone offset
+            0, # timezone accuracy
+            65535, # snapshot length
+            192 # PPI linktype
+        ))
+
+    def write(self, data, timestamp, port):
+        """
+        Write a packet to a pcap file
+
+        'data' should be a string containing the packet data.
+        'timestamp' should be a float.
+        'port' should be an integer port number.
+        """
+        ppi_len = PPIPktHeader.size + PPIAggregateField.size
+        self.stream.write(PcapPktHeader.pack(
+            int(timestamp), # timestamp seconds
+            int((timestamp - int(timestamp)) * 10**6), # timestamp microseconds
+            len(data) + ppi_len, # truncated length
+            len(data) + ppi_len # un-truncated length
+        ))
+        self.stream.write(PPIPktHeader.pack(
+            0, # version
+            0, # flags
+            ppi_len, # length
+            1, # ethernet dlt
+        ))
+        self.stream.write(PPIAggregateField.pack(8, PPIAggregateField.size - 4, port))
+        self.stream.write(data)
+
+    def close(self):
+        self.stream.close()
+
+if __name__ == "__main__":
+    import time
+    print("Writing test pcap to test.pcap")
+    pcap_writer = PcapWriter("test.pcap")
+    pcap_writer.write("\x00\x01\x02\x03\x04\x05\x00\x0a\x0b\x0c\x0d\x0e\x08\x00", time.time(), 42)
+    pcap_writer.close()
diff --git a/Fabric/Utilities/src/python/oftest/test_parse.py b/Fabric/Utilities/src/python/oftest/test_parse.py
new file mode 100755
index 0000000..d4762ef
--- /dev/null
+++ b/Fabric/Utilities/src/python/oftest/test_parse.py
@@ -0,0 +1,195 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+#!/usr/bin/env python
+import unittest
+import parse
+import packet as scapy
+
+class TestPacketToFlowMatchV3(unittest.TestCase):
+    def test_tcp(self):
+        import loxi.of12 as ofp
+        self.maxDiff = None
+        pkt = scapy.Ether(dst='00:01:02:03:04:05', src='00:06:07:08:09:0a')/ \
+            scapy.IP(src='192.168.0.1', dst='192.168.0.2', tos=2 | (32 << 2), ttl=64)/ \
+            scapy.TCP(sport=1234, dport=80)
+        expected = [
+            ofp.oxm.eth_dst([0x00, 0x01, 0x02, 0x03, 0x04, 0x05]),
+            ofp.oxm.eth_src([0x00, 0x06, 0x07, 0x08, 0x09, 0x0a]),
+            ofp.oxm.eth_type(0x0800),
+            ofp.oxm.vlan_vid(ofp.OFP_VLAN_NONE),
+            ofp.oxm.ip_proto(6),
+            ofp.oxm.ip_dscp(32),
+            ofp.oxm.ip_ecn(2),
+            ofp.oxm.ipv4_src(0xc0a80001),
+            ofp.oxm.ipv4_dst(0xc0a80002),
+            ofp.oxm.tcp_src(1234),
+            ofp.oxm.tcp_dst(80)
+        ]
+        result = parse.packet_to_flow_match_v3(pkt).oxm_list
+        self.assertEquals([x.show() for x in expected], [x.show() for x in result])
+
+    def test_udp(self):
+        import loxi.of12 as ofp
+        self.maxDiff = None
+        pkt = scapy.Ether(dst='00:01:02:03:04:05', src='00:06:07:08:09:0a')/ \
+            scapy.IP(src='192.168.0.1', dst='192.168.0.2', tos=2 | (32 << 2), ttl=64)/ \
+            scapy.UDP(sport=1234, dport=80)
+        expected = [
+            ofp.oxm.eth_dst([0x00, 0x01, 0x02, 0x03, 0x04, 0x05]),
+            ofp.oxm.eth_src([0x00, 0x06, 0x07, 0x08, 0x09, 0x0a]),
+            ofp.oxm.eth_type(0x0800),
+            ofp.oxm.vlan_vid(ofp.OFP_VLAN_NONE),
+            ofp.oxm.ip_proto(17),
+            ofp.oxm.ip_dscp(32),
+            ofp.oxm.ip_ecn(2),
+            ofp.oxm.ipv4_src(0xc0a80001),
+            ofp.oxm.ipv4_dst(0xc0a80002),
+            ofp.oxm.udp_src(1234),
+            ofp.oxm.udp_dst(80)
+        ]
+        result = parse.packet_to_flow_match_v3(pkt).oxm_list
+        self.assertEquals([x.show() for x in expected], [x.show() for x in result])
+
+    def test_icmp(self):
+        import loxi.of12 as ofp
+        self.maxDiff = None
+        pkt = scapy.Ether(dst='00:01:02:03:04:05', src='00:06:07:08:09:0a')/ \
+            scapy.IP(src='192.168.0.1', dst='192.168.0.2', tos=2 | (32 << 2), ttl=64)/ \
+            scapy.ICMP(type=8, code=1)
+        expected = [
+            ofp.oxm.eth_dst([0x00, 0x01, 0x02, 0x03, 0x04, 0x05]),
+            ofp.oxm.eth_src([0x00, 0x06, 0x07, 0x08, 0x09, 0x0a]),
+            ofp.oxm.eth_type(0x0800),
+            ofp.oxm.vlan_vid(ofp.OFP_VLAN_NONE),
+            ofp.oxm.ip_proto(1),
+            ofp.oxm.ip_dscp(32),
+            ofp.oxm.ip_ecn(2),
+            ofp.oxm.ipv4_src(0xc0a80001),
+            ofp.oxm.ipv4_dst(0xc0a80002),
+            ofp.oxm.icmpv4_type(8),
+            ofp.oxm.icmpv4_code(1)
+        ]
+        result = parse.packet_to_flow_match_v3(pkt).oxm_list
+        self.assertEquals([x.show() for x in expected], [x.show() for x in result])
+
+    def test_arp(self):
+        import loxi.of12 as ofp
+        self.maxDiff = None
+        pkt = scapy.Ether(dst='00:01:02:03:04:05', src='00:06:07:08:09:0a')/ \
+            scapy.ARP(hwsrc='00:01:02:03:04:05', hwdst='00:06:07:08:09:0a', \
+                      psrc='192.168.0.1', pdst='192.168.0.2', op=1)
+        expected = [
+            ofp.oxm.eth_dst([0x00, 0x01, 0x02, 0x03, 0x04, 0x05]),
+            ofp.oxm.eth_src([0x00, 0x06, 0x07, 0x08, 0x09, 0x0a]),
+            ofp.oxm.eth_type(0x0806),
+            ofp.oxm.vlan_vid(ofp.OFP_VLAN_NONE),
+            ofp.oxm.arp_op(1),
+            ofp.oxm.arp_spa(0xc0a80001),
+            ofp.oxm.arp_tpa(0xc0a80002),
+            ofp.oxm.arp_sha([0x00, 0x01, 0x02, 0x03, 0x04, 0x05]),
+            ofp.oxm.arp_tha([0x00, 0x06, 0x07, 0x08, 0x09, 0x0a]),
+        ]
+        result = parse.packet_to_flow_match_v3(pkt).oxm_list
+        self.assertEquals([x.show() for x in expected], [x.show() for x in result])
+
+    def test_tcpv6(self):
+        import loxi.of12 as ofp
+        self.maxDiff = None
+        pkt = scapy.Ether(dst='00:01:02:03:04:05', src='00:06:07:08:09:0a')/ \
+            scapy.IPv6(src="::1", dst="::2", nh=6, tc=2 | (32 << 2), fl=7)/ \
+            scapy.TCP(sport=1234, dport=80)
+        expected = [
+            ofp.oxm.eth_dst([0x00, 0x01, 0x02, 0x03, 0x04, 0x05]),
+            ofp.oxm.eth_src([0x00, 0x06, 0x07, 0x08, 0x09, 0x0a]),
+            ofp.oxm.eth_type(0x86dd),
+            ofp.oxm.vlan_vid(ofp.OFP_VLAN_NONE),
+            ofp.oxm.ip_proto(6),
+            ofp.oxm.ip_dscp(32),
+            ofp.oxm.ip_ecn(2),
+            ofp.oxm.ipv6_src("\x00" * 15 + "\x01"),
+            ofp.oxm.ipv6_dst("\x00" * 15 + "\x02"),
+            ofp.oxm.ipv6_flabel(7),
+            ofp.oxm.tcp_src(1234),
+            ofp.oxm.tcp_dst(80)
+        ]
+        result = parse.packet_to_flow_match_v3(pkt).oxm_list
+        self.assertEquals([x.show() for x in expected], [x.show() for x in result])
+
+    def test_icmpv6(self):
+        import loxi.of12 as ofp
+        self.maxDiff = None
+        pkt = scapy.Ether(dst='00:01:02:03:04:05', src='00:06:07:08:09:0a')/ \
+            scapy.IPv6(src="::1", dst="::2", tc=2 | (32 << 2), fl=7)/ \
+            scapy.ICMPv6EchoRequest()
+        expected = [
+            ofp.oxm.eth_dst([0x00, 0x01, 0x02, 0x03, 0x04, 0x05]),
+            ofp.oxm.eth_src([0x00, 0x06, 0x07, 0x08, 0x09, 0x0a]),
+            ofp.oxm.eth_type(0x86dd),
+            ofp.oxm.vlan_vid(ofp.OFP_VLAN_NONE),
+            ofp.oxm.ip_proto(0x3a),
+            ofp.oxm.ip_dscp(32),
+            ofp.oxm.ip_ecn(2),
+            ofp.oxm.ipv6_src("\x00" * 15 + "\x01"),
+            ofp.oxm.ipv6_dst("\x00" * 15 + "\x02"),
+            ofp.oxm.ipv6_flabel(7),
+            ofp.oxm.icmpv6_type(128),
+            ofp.oxm.icmpv6_code(0)
+        ]
+        result = parse.packet_to_flow_match_v3(pkt).oxm_list
+        self.assertEquals([x.show() for x in expected], [x.show() for x in result])
+
+    def test_vlan(self):
+        import loxi.of12 as ofp
+        self.maxDiff = None
+        pkt = scapy.Ether(dst='00:01:02:03:04:05', src='00:06:07:08:09:0a')/ \
+            scapy.Dot1Q(vlan=50, prio=5)/ \
+            scapy.IP(src='192.168.0.1', dst='192.168.0.2', tos=2 | (32 << 2), ttl=64)/ \
+            scapy.TCP(sport=1234, dport=80)
+        expected = [
+            ofp.oxm.eth_dst([0x00, 0x01, 0x02, 0x03, 0x04, 0x05]),
+            ofp.oxm.eth_src([0x00, 0x06, 0x07, 0x08, 0x09, 0x0a]),
+            ofp.oxm.eth_type(0x0800),
+            ofp.oxm.vlan_vid(50),
+            ofp.oxm.vlan_pcp(5),
+            ofp.oxm.ip_proto(6),
+            ofp.oxm.ip_dscp(32),
+            ofp.oxm.ip_ecn(2),
+            ofp.oxm.ipv4_src(0xc0a80001),
+            ofp.oxm.ipv4_dst(0xc0a80002),
+            ofp.oxm.tcp_src(1234),
+            ofp.oxm.tcp_dst(80)
+        ]
+        result = parse.packet_to_flow_match_v3(pkt).oxm_list
+        self.assertEquals([x.show() for x in expected], [x.show() for x in result])
+
+    def test_unknown_ethertype(self):
+        import loxi.of12 as ofp
+        self.maxDiff = None
+        pkt = scapy.Ether(dst='00:01:02:03:04:05', src='00:06:07:08:09:0a', type=0x0801)/ \
+            ('\x11' * 20)
+        expected = [
+            ofp.oxm.eth_dst([0x00, 0x01, 0x02, 0x03, 0x04, 0x05]),
+            ofp.oxm.eth_src([0x00, 0x06, 0x07, 0x08, 0x09, 0x0a]),
+            ofp.oxm.eth_type(0x0801),
+            ofp.oxm.vlan_vid(ofp.OFP_VLAN_NONE),
+        ]
+        result = parse.packet_to_flow_match_v3(pkt).oxm_list
+        self.assertEquals([x.show() for x in expected], [x.show() for x in result])
+
+
+if __name__ == '__main__':
+    unittest.main(verbosity=2)
diff --git a/Fabric/Utilities/src/python/oftest/testutils.py b/Fabric/Utilities/src/python/oftest/testutils.py
new file mode 100755
index 0000000..3a147c7
--- /dev/null
+++ b/Fabric/Utilities/src/python/oftest/testutils.py
@@ -0,0 +1,2262 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+import sys
+import copy
+import logging
+import types
+import time
+import re
+from Queue import Queue
+
+import packet as scapy
+
+import oftest
+import oftest.controller
+import oftest.dataplane
+import oftest.parse
+import oftest.ofutils
+import ofp
+
+global skipped_test_count
+skipped_test_count = 0
+
+_import_blacklist = set(locals().keys())
+
+# Some useful defines
+IP_ETHERTYPE = 0x800
+TCP_PROTOCOL = 0x6
+UDP_PROTOCOL = 0x11
+
+MINSIZE = 0
+
+def delete_all_flows(ctrl, send_barrier=True):
+    """
+    Delete all flows on the switch
+    @param ctrl The controller object for the test
+    @param send_barrier Whether or not to send a barrier message
+    """
+
+    logging.info("Deleting all flows")
+    msg = ofp.message.flow_delete()
+    if ofp.OFP_VERSION in [1, 2]:
+        msg.match.wildcards = ofp.OFPFW_ALL
+        msg.out_port = ofp.OFPP_NONE
+        msg.buffer_id = 0xffffffff
+    elif ofp.OFP_VERSION >= 3:
+        msg.table_id = ofp.OFPTT_ALL
+        msg.buffer_id = ofp.OFP_NO_BUFFER
+        msg.out_port = ofp.OFPP_ANY
+        msg.out_group = ofp.OFPG_ANY
+    ctrl.message_send(msg)
+    if send_barrier:
+        do_barrier(ctrl)
+    return 0 # for backwards compatibility
+
+def delete_all_groups(ctrl):
+    """
+    Delete all groups on the switch
+    @param ctrl The controller object for the test
+    """
+
+    logging.info("Deleting all groups")
+    msg = ofp.message.group_delete(group_id=ofp.OFPG_ALL)
+    ctrl.message_send(msg)
+    do_barrier(ctrl)
+
+def delete_groups(ctrl, group_queue=Queue()):
+    """
+    Delete all groups on list
+    @param ctrl The controller object for the test
+    :param group_queue:
+    """
+    logging.info("Deleting groups")
+    while (not group_queue.empty()):
+        msg = ofp.message.group_delete(group_id=group_queue.get())
+        ctrl.message_send(msg)
+        do_barrier(ctrl)
+
+def delete_group(ctrl, group_id):
+    """
+    Delete a single group
+    @param ctrl The controller object for the test
+    :param group_id
+    """
+    logging.info("Deleting a single group with groupId:" + str(group_id))
+    msg = ofp.message.group_delete(group_id=group_id)
+    ctrl.message_send(msg)
+    do_barrier(ctrl)
+
+def required_wildcards(parent):
+    w = test_param_get('required_wildcards', default='default')
+    if w == 'l3-l4':
+        return (ofp.OFPFW_NW_SRC_ALL | ofp.OFPFW_NW_DST_ALL | ofp.OFPFW_NW_TOS
+                | ofp.OFPFW_NW_PROTO | ofp.OFPFW_TP_SRC | ofp.OFPFW_TP_DST)
+    else:
+        return 0
+
+def simple_packet(content='00 00 00 11 33 55 00 00 00 11 22 33 81 00 00 03 '
+                '08 00 45 00 00 2e 04 d2 00 00 7f 00 b2 47 c0 a8 '
+                '01 64 c0 a8 02 02 00 00 00 00 00 00 00 00 00 00 '
+                '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'):
+
+    pkt = ''.join(content.split(" ")).decode('hex')
+    pkt = scapy.Ether(pkt)
+    if len(pkt) < 64:
+        pkt = pkt/("D" * (64 - len(pkt)))
+    #scapy.hexdump(pkt)
+    return pkt
+
+def simple_tcp_packet(pktlen=100,
+                      eth_dst='00:01:02:03:04:05',
+                      eth_src='00:06:07:08:09:0a',
+                      dl_vlan_enable=False,
+                      vlan_vid=0,
+                      outer_vlan=None,
+                      vlan_pcp=0,
+                      dl_vlan_cfi=0,
+                      ip_src='192.168.0.1',
+                      ip_dst='192.168.0.2',
+                      ip_tos=0,
+                      ip_ttl=64,
+                      tcp_sport=1234,
+                      tcp_dport=80,
+                      tcp_flags="S",
+                      ip_ihl=None,
+                      ip_options=False
+                      ):
+    """
+    Return a simple dataplane TCP packet
+
+    Supports a few parameters:
+    @param len Length of packet in bytes w/o CRC
+    @param eth_dst Destinatino MAC
+    @param eth_src Source MAC
+    @param dl_vlan_enable True if the packet is with vlan, False otherwise
+    @param vlan_vid VLAN ID
+    @param vlan_pcp VLAN priority
+    @param ip_src IP source
+    @param ip_dst IP destination
+    @param ip_tos IP ToS
+    @param ip_ttl IP TTL
+    @param tcp_dport TCP destination port
+    @param tcp_sport TCP source port
+    @param tcp_flags TCP Control flags
+
+    Generates a simple TCP request.  Users
+    shouldn't assume anything about this packet other than that
+    it is a valid ethernet/IP/TCP frame.
+    """
+
+    if MINSIZE > pktlen:
+        pktlen = MINSIZE
+
+    # Note Dot1Q.id is really CFI
+    if (dl_vlan_enable):
+        pkt = scapy.Ether( dst=eth_dst, src=eth_src )
+        if outer_vlan:
+            pkt = pkt/scapy.Dot1Q(prio=vlan_pcp, id=dl_vlan_cfi, vlan=outer_vlan)
+
+        pkt = pkt/scapy.Dot1Q( prio=vlan_pcp, id=dl_vlan_cfi, vlan=vlan_vid )/ \
+              scapy.IP(src=ip_src, dst=ip_dst, tos=ip_tos, ttl=ip_ttl, ihl=ip_ihl)/ \
+              scapy.TCP(sport=tcp_sport, dport=tcp_dport, flags=tcp_flags)
+    else:
+        if not ip_options:
+            pkt = scapy.Ether(dst=eth_dst, src=eth_src)/ \
+                scapy.IP(src=ip_src, dst=ip_dst, tos=ip_tos, ttl=ip_ttl, ihl=ip_ihl)/ \
+                scapy.TCP(sport=tcp_sport, dport=tcp_dport, flags=tcp_flags)
+        else:
+            pkt = scapy.Ether(dst=eth_dst, src=eth_src)/ \
+                scapy.IP(src=ip_src, dst=ip_dst, tos=ip_tos, ttl=ip_ttl, ihl=ip_ihl, options=ip_options)/ \
+                scapy.TCP(sport=tcp_sport, dport=tcp_dport, flags=tcp_flags)
+
+    pkt = pkt/("D" * (pktlen - len(pkt)))
+
+    return pkt
+
+def simple_tcpv6_packet(pktlen=100,
+                        eth_dst='00:01:02:03:04:05',
+                        eth_src='00:06:07:08:09:0a',
+                        dl_vlan_enable=False,
+                        vlan_vid=0,
+                        vlan_pcp=0,
+                        ipv6_src='2001:db8:85a3::8a2e:370:7334',
+                        ipv6_dst='2001:db8:85a3::8a2e:370:7335',
+                        ipv6_tc=0,
+                        ipv6_hlim=64,
+                        ipv6_fl=0,
+                        tcp_sport=1234,
+                        tcp_dport=80,
+                        tcp_flags="S"):
+    """
+    Return a simple IPv6/TCP packet
+
+    Supports a few parameters:
+    @param len Length of packet in bytes w/o CRC
+    @param eth_dst Destination MAC
+    @param eth_src Source MAC
+    @param dl_vlan_enable True if the packet is with vlan, False otherwise
+    @param vlan_vid VLAN ID
+    @param vlan_pcp VLAN priority
+    @param ipv6_src IPv6 source
+    @param ipv6_dst IPv6 destination
+    @param ipv6_tc IPv6 traffic class
+    @param ipv6_ttl IPv6 hop limit
+    @param ipv6_fl IPv6 flow label
+    @param tcp_dport TCP destination port
+    @param tcp_sport TCP source port
+    @param tcp_flags TCP Control flags
+
+    Generates a simple TCP request. Users shouldn't assume anything about this
+    packet other than that it is a valid ethernet/IPv6/TCP frame.
+    """
+
+    if MINSIZE > pktlen:
+        pktlen = MINSIZE
+
+    pkt = scapy.Ether(dst=eth_dst, src=eth_src)
+    if dl_vlan_enable or vlan_vid or vlan_pcp:
+        pkt /= scapy.Dot1Q(vlan=vlan_vid, prio=vlan_pcp)
+    pkt /= scapy.IPv6(src=ipv6_src, dst=ipv6_dst, fl=ipv6_fl, tc=ipv6_tc, hlim=ipv6_hlim)
+    pkt /= scapy.TCP(sport=tcp_sport, dport=tcp_dport, flags=tcp_flags)
+    pkt /= ("D" * (pktlen - len(pkt)))
+
+    return pkt
+
+def simple_udp_packet(pktlen=100,
+                      eth_dst='00:01:02:03:04:05',
+                      eth_src='00:06:07:08:09:0a',
+                      dl_vlan_enable=False,
+                      vlan_vid=0,
+                      vlan_pcp=0,
+                      dl_vlan_cfi=0,
+                      ip_src='192.168.0.1',
+                      ip_dst='192.168.0.2',
+                      ip_tos=0,
+                      ip_ttl=64,
+                      udp_sport=1234,
+                      udp_dport=80,
+                      ip_ihl=None,
+                      ip_options=False
+                      ):
+    """
+    Return a simple dataplane UDP packet
+
+    Supports a few parameters:
+    @param len Length of packet in bytes w/o CRC
+    @param eth_dst Destination MAC
+    @param eth_src Source MAC
+    @param dl_vlan_enable True if the packet is with vlan, False otherwise
+    @param vlan_vid VLAN ID
+    @param vlan_pcp VLAN priority
+    @param ip_src IP source
+    @param ip_dst IP destination
+    @param ip_tos IP ToS
+    @param ip_ttl IP TTL
+    @param udp_dport UDP destination port
+    @param udp_sport UDP source port
+
+    Generates a simple UDP packet. Users shouldn't assume anything about
+    this packet other than that it is a valid ethernet/IP/UDP frame.
+    """
+
+    if MINSIZE > pktlen:
+        pktlen = MINSIZE
+
+    # Note Dot1Q.id is really CFI
+    if (dl_vlan_enable):
+        pkt = scapy.Ether(dst=eth_dst, src=eth_src)/ \
+            scapy.Dot1Q(prio=vlan_pcp, id=dl_vlan_cfi, vlan=vlan_vid)/ \
+            scapy.IP(src=ip_src, dst=ip_dst, tos=ip_tos, ttl=ip_ttl, ihl=ip_ihl)/ \
+            scapy.UDP(sport=udp_sport, dport=udp_dport)
+    else:
+        if not ip_options:
+            pkt = scapy.Ether(dst=eth_dst, src=eth_src)/ \
+                scapy.IP(src=ip_src, dst=ip_dst, tos=ip_tos, ttl=ip_ttl, ihl=ip_ihl)/ \
+                scapy.UDP(sport=udp_sport, dport=udp_dport)
+        else:
+            pkt = scapy.Ether(dst=eth_dst, src=eth_src)/ \
+                scapy.IP(src=ip_src, dst=ip_dst, tos=ip_tos, ttl=ip_ttl, ihl=ip_ihl, options=ip_options)/ \
+                scapy.UDP(sport=udp_sport, dport=udp_dport)
+
+    pkt = pkt/("D" * (pktlen - len(pkt)))
+
+    return pkt
+
+
+def simple_tcp_packet_two_vlan(pktlen=100,
+                      eth_dst='00:01:02:03:04:05',
+                      eth_src='00:06:07:08:09:0a',
+                      out_dl_vlan_enable=False,
+                      in_dl_vlan_enable=False,
+                      out_vlan_vid=0,
+                      out_vlan_pcp=0,
+                      out_vlan_tpid=0x8100,
+                      out_dl_vlan_cfi=0,
+                      in_vlan_vid=0,
+                      in_vlan_pcp=0,
+                      in_dl_vlan_cfi=0,
+                      ip_src='192.168.0.1',
+                      ip_dst='192.168.0.2',
+                      ip_tos=0,
+                      ip_ttl=64,
+                      tcp_sport=1234,
+                      tcp_dport=80,
+                      tcp_flags="S",
+                      ip_ihl=None,
+                      ip_options=False
+                      ):
+    """
+    Return a simple dataplane TCP packet
+
+    Supports a few parameters:
+    @param len Length of packet in bytes w/o CRC
+    @param eth_dst Destinatino MAC
+    @param eth_src Source MAC
+    @param dl_vlan_enable True if the packet is with vlan, False otherwise
+    @param vlan_vid VLAN ID
+    @param vlan_pcp VLAN priority
+    @param ip_src IP source
+    @param ip_dst IP destination
+    @param ip_tos IP ToS
+    @param ip_ttl IP TTL
+    @param tcp_dport TCP destination port
+    @param tcp_sport TCP source port
+    @param tcp_flags TCP Control flags
+
+    Generates a simple TCP request.  Users
+    shouldn't assume anything about this packet other than that
+    it is a valid ethernet/IP/TCP frame.
+    """
+
+    if MINSIZE > pktlen:
+        pktlen = MINSIZE
+
+    # Note Dot1Q.id is really CFI
+    if (out_dl_vlan_enable and in_dl_vlan_enable):
+        pkt = scapy.Ether(dst=eth_dst, src=eth_src, type=out_vlan_tpid)/ \
+            scapy.Dot1Q(prio=out_vlan_pcp, id=out_dl_vlan_cfi, vlan=out_vlan_vid)
+
+        if in_dl_vlan_enable:
+            pkt = pkt/scapy.Dot1Q(prio=in_vlan_pcp, id=in_dl_vlan_cfi, vlan=in_vlan_vid)
+
+        pkt = pkt/scapy.IP(src=ip_src, dst=ip_dst, tos=ip_tos, ttl=ip_ttl, ihl=ip_ihl)/ \
+            scapy.TCP(sport=tcp_sport, dport=tcp_dport, flags=tcp_flags)
+    elif (out_dl_vlan_enable and (not in_dl_vlan_enable)):
+        pkt = scapy.Ether(dst=eth_dst, src=eth_src)/ \
+            scapy.Dot1Q(prio=out_vlan_pcp, id=out_dl_vlan_cfi, vlan=out_vlan_vid)/ \
+            scapy.IP(src=ip_src, dst=ip_dst, tos=ip_tos, ttl=ip_ttl, ihl=ip_ihl)/ \
+            scapy.TCP(sport=tcp_sport, dport=tcp_dport, flags=tcp_flags)
+    elif ((not out_dl_vlan_enable) and in_dl_vlan_enable):
+        assert(0) #shall not have this caes
+    else:
+        if not ip_options:
+            pkt = scapy.Ether(dst=eth_dst, src=eth_src)/ \
+                scapy.IP(src=ip_src, dst=ip_dst, tos=ip_tos, ttl=ip_ttl, ihl=ip_ihl)/ \
+                scapy.TCP(sport=tcp_sport, dport=tcp_dport, flags=tcp_flags)
+        else:
+            pkt = scapy.Ether(dst=eth_dst, src=eth_src)/ \
+                scapy.IP(src=ip_src, dst=ip_dst, tos=ip_tos, ttl=ip_ttl, ihl=ip_ihl, options=ip_options)/ \
+                scapy.TCP(sport=tcp_sport, dport=tcp_dport, flags=tcp_flags)
+
+    pkt = pkt/("D" * (pktlen - len(pkt)))
+
+    return pkt
+
+def simple_vxlan_packet(eth_dst='00:01:02:03:04:05',
+                      eth_src='00:06:07:08:09:0a',
+                      dl_vlan_enable=False,
+                      vlan_vid=0,
+                      vlan_pcp=0,
+                      dl_vlan_cfi=0,
+                      ip_src='192.168.0.1',
+                      ip_dst='192.168.0.2',
+                      ip_tos=0,
+                      ip_ttl=64,
+                      udp_sport=1234,
+                      udp_dport=4789,
+                      vnid=1,
+                      inner_payload=None,
+                      ip_ihl=None,
+                      ip_options=False
+                      ):
+    """
+    Return a simple dataplane UDP packet
+
+    Supports a few parameters:
+    @param len Length of packet in bytes w/o CRC
+    @param eth_dst Destination MAC
+    @param eth_src Source MAC
+    @param dl_vlan_enable True if the packet is with vlan, False otherwise
+    @param vlan_vid VLAN ID
+    @param vlan_pcp VLAN priority
+    @param ip_src IP source
+    @param ip_dst IP destination
+    @param ip_tos IP ToS
+    @param ip_ttl IP TTL
+    @param udp_dport UDP destination port
+    @param udp_sport UDP source port
+    @param inner_pyload inner pacekt content
+    Generates a simple UDP packet. Users shouldn't assume anything about
+    this packet other than that it is a valid ethernet/IP/UDP frame.
+    """
+
+    # Note Dot1Q.id is really CFI
+    if (dl_vlan_enable):
+        pkt = scapy.Ether(dst=eth_dst, src=eth_src)/ \
+            scapy.Dot1Q(prio=vlan_pcp, id=dl_vlan_cfi, vlan=vlan_vid)/ \
+            scapy.IP(src=ip_src, dst=ip_dst, tos=ip_tos, ttl=ip_ttl, ihl=ip_ihl)/ \
+            scapy.UDP(sport=udp_sport, dport=udp_dport)
+    else:
+        if not ip_options:
+            pkt = scapy.Ether(dst=eth_dst, src=eth_src)/ \
+                scapy.IP(src=ip_src, dst=ip_dst, tos=ip_tos, ttl=ip_ttl, ihl=ip_ihl)/ \
+                scapy.UDP(sport=udp_sport, dport=udp_dport)
+        else:
+            pkt = scapy.Ether(dst=eth_dst, src=eth_src)/ \
+                scapy.IP(src=ip_src, dst=ip_dst, tos=ip_tos, ttl=ip_ttl, ihl=ip_ihl, options=ip_options)/ \
+                scapy.UDP(sport=udp_sport, dport=udp_dport)
+
+    #add vxlan header
+    pkt = pkt/scapy.VXLAN(vni=vnid)
+    #add innder payload
+    if inner_payload!=None:
+        pkt=pkt/inner_payload
+
+    return pkt
+
+def mpls_packet(pktlen=100,
+                      eth_dst='00:01:02:03:04:05',
+                      eth_src='00:06:07:08:09:0a',
+                      dl_vlan_enable=False,
+                      vlan_vid=0,
+                      vlan_pcp=0,
+                      dl_vlan_cfi=0,
+                      ip_src='192.168.0.1',
+                      ip_dst='192.168.0.2',
+                      ip_tos=0,
+                      ip_ttl=64,
+                      tcp_sport=1234,
+                      tcp_dport=80,
+                      tcp_flags="S",
+                      ip_ihl=None,
+                      ip_options=False,
+                      label=None,
+                      inner_payload=True,
+		      encapsulated_ethernet=False,
+		      encapsulated_eth_src='01:02:03:04:05:11',
+		      encapsulated_eth_dst='01:02:03:04:05:22'
+                      ):
+    if MINSIZE > pktlen:
+        pktlen = MINSIZE
+
+    # Note Dot1Q.id is really CFI
+    if (dl_vlan_enable):
+        pkt = scapy.Ether(dst=eth_dst, src=eth_src)/ \
+            scapy.Dot1Q(prio=vlan_pcp, id=dl_vlan_cfi, vlan=vlan_vid)
+    else:
+        pkt = scapy.Ether(dst=eth_dst, src=eth_src)
+
+    #add MPLS header
+    for i in range(len(label)):
+        l,c,s,t=label[i]
+        pkt = pkt/scapy.MPLS(label=l, cos=c, s=s, ttl=t)
+
+    #add innder payload
+    if inner_payload!=None:
+        if not encapsulated_ethernet:
+        	pkt=pkt / \
+           	   scapy.IP(src=ip_src, dst=ip_dst, tos=ip_tos, ttl=ip_ttl, ihl=ip_ihl)/ \
+            	   scapy.TCP(sport=tcp_sport, dport=tcp_dport, flags=tcp_flags)
+        else:
+	       	pkt=pkt / \
+		   scapy.Ether(dst=encapsulated_eth_dst, src=encapsulated_eth_src)/ \
+           	   scapy.IP(src=ip_src, dst=ip_dst, tos=ip_tos, ttl=ip_ttl, ihl=ip_ihl)/ \
+            	   scapy.TCP(sport=tcp_sport, dport=tcp_dport, flags=tcp_flags)
+
+    pkt = pkt/("D" * (pktlen - len(pkt)))
+
+    return pkt
+
+def pw_packet(pktlen=100,
+                      out_eth_dst='00:01:02:03:04:05',
+                      out_eth_src='00:06:07:08:09:0a',
+                      label=None,
+                      cw=None,
+                      in_eth_dst='00:01:02:03:04:05',
+                      in_eth_src='00:06:07:08:09:0a',
+                      out_dl_vlan_enable=False,
+                      in_dl_vlan_enable=False,
+                      out_vlan_vid=0,
+                      out_vlan_pcp=0,
+                      out_dl_vlan_cfi=0,
+                      in_vlan_vid=0,
+                      in_vlan_pcp=0,
+                      in_dl_vlan_cfi=0,
+                      ip_src='192.168.0.1',
+                      ip_dst='192.168.0.2',
+                      ip_tos=0,
+                      ip_ttl=64,
+                      tcp_sport=1234,
+                      tcp_dport=80,
+                      tcp_flags="S",
+                      ip_ihl=None,
+                      ip_options=False
+                      ):
+    """
+    Return a simple dataplane TCP packet encapsulated
+    in a pw packet
+    """
+
+    # Add the outer ethernet header
+    if MINSIZE > pktlen:
+        pktlen = MINSIZE
+
+    pkt = scapy.Ether(dst=out_eth_dst, src=out_eth_src)
+
+    #add MPLS header
+    for i in range(len(label)):
+        l,c,s,t=label[i]
+        pkt = pkt/scapy.MPLS(label=l, cos=c, s=s, ttl=t)
+
+    #add the PW CW
+    l,c,s,t=cw
+    pkt = pkt/scapy.MPLS(label=l, cos=c, s=s, ttl=t)
+
+    # Note Dot1Q.id is really CFI
+    if (out_dl_vlan_enable and in_dl_vlan_enable):
+
+        pkt = pkt/scapy.Ether(dst=in_eth_dst, src=in_eth_src)/ \
+            scapy.Dot1Q(prio=out_vlan_pcp, id=out_dl_vlan_cfi, vlan=out_vlan_vid)
+
+        pkt = pkt/scapy.Dot1Q(prio=in_vlan_pcp, id=in_dl_vlan_cfi, vlan=in_vlan_vid)
+
+        pkt = pkt/scapy.IP(src=ip_src, dst=ip_dst, tos=ip_tos, ttl=ip_ttl, ihl=ip_ihl)/ \
+            scapy.TCP(sport=tcp_sport, dport=tcp_dport, flags=tcp_flags)
+
+    elif (out_dl_vlan_enable and (not in_dl_vlan_enable)):
+
+        pkt = pkt/scapy.Ether(dst=in_eth_dst, src=in_eth_src)/ \
+            scapy.Dot1Q(prio=out_vlan_pcp, id=out_dl_vlan_cfi, vlan=out_vlan_vid)/ \
+            scapy.IP(src=ip_src, dst=ip_dst, tos=ip_tos, ttl=ip_ttl, ihl=ip_ihl)/ \
+            scapy.TCP(sport=tcp_sport, dport=tcp_dport, flags=tcp_flags)
+
+    elif ((not out_dl_vlan_enable) and in_dl_vlan_enable):
+
+        assert(0) #shall not have this caes
+
+    else:
+        if not ip_options:
+            pkt = pkt/scapy.Ether(dst=in_eth_dst, src=in_eth_src)/ \
+                scapy.IP(src=ip_src, dst=ip_dst, tos=ip_tos, ttl=ip_ttl, ihl=ip_ihl)/ \
+                scapy.TCP(sport=tcp_sport, dport=tcp_dport, flags=tcp_flags)
+        else:
+            pkt = pkt/scapy.Ether(dst=in_eth_dst, src=in_eth_src)/ \
+                scapy.IP(src=ip_src, dst=ip_dst, tos=ip_tos, ttl=ip_ttl, ihl=ip_ihl, options=ip_options)/ \
+                scapy.TCP(sport=tcp_sport, dport=tcp_dport, flags=tcp_flags)
+
+    pkt = pkt/("D" * (pktlen - len(pkt)))
+
+    return pkt
+
+def mplsv6_packet(pktlen=100,
+                      eth_dst='00:01:02:03:04:05',
+                      eth_src='00:06:07:08:09:0a',
+                      dl_vlan_enable=False,
+                      vlan_vid=0,
+                      vlan_pcp=0,
+                      dl_vlan_cfi=0,
+                      ipv6_src='2001:db8:85a3::8a2e:370:7334',
+                      ipv6_dst='2001:db8:85a3::8a2e:370:7335',
+                      ipv6_tc=0,
+                      ipv6_hlim=64,
+                      ipv6_fl=0,
+                      tcp_sport=1234,
+                      tcp_dport=80,
+                      tcp_flags="S",
+                      label=None,
+                      inner_payload=True
+                      ):
+    if MINSIZE > pktlen:
+        pktlen = MINSIZE
+
+    # Note Dot1Q.id is really CFI
+    if (dl_vlan_enable):
+        pkt = scapy.Ether(dst=eth_dst, src=eth_src)/ \
+            scapy.Dot1Q(prio=vlan_pcp, id=dl_vlan_cfi, vlan=vlan_vid)
+    else:
+        pkt = scapy.Ether(dst=eth_dst, src=eth_src)
+
+    #add MPLS header
+    for i in range(len(label)):
+        l,c,s,t=label[i]
+        pkt = pkt/scapy.MPLS(label=l, cos=c, s=s, ttl=t)
+
+    #add innder payload
+    if inner_payload!=None:
+        pkt=pkt / \
+            scapy.IPv6(src=ipv6_src, dst=ipv6_dst, fl=ipv6_fl, tc=ipv6_tc, hlim=ipv6_hlim)/ \
+            scapy.TCP(sport=tcp_sport, dport=tcp_dport, flags=tcp_flags)
+
+    pkt = pkt/("D" * (pktlen - len(pkt)))
+
+    return pkt
+
+def simple_mpls_packet(eth_dst='00:01:02:03:04:05',
+                      eth_src='00:06:07:08:09:0a',
+                      dl_vlan_enable=False,
+                      vlan_vid=0,
+                      vlan_pcp=0,
+                      dl_vlan_cfi=0,
+                      label=None,
+                      inner_payload=None
+                      ):
+    """
+    Return a simple dataplane MPLS packet
+
+    Supports a few parameters:
+    @param len Length of packet in bytes w/o CRC
+    @param eth_dst Destination MAC
+    @param eth_src Source MAC
+    @param dl_vlan_enable True if the packet is with vlan, False otherwise
+    @param vlan_vid VLAN ID
+    @param vlan_pcp VLAN priority
+    @param inner_pyload inner pacekt content
+    Generates a simple MPLS packet. Users shouldn't assume anything about
+    this packet other than that it is a valid ethernet/IP/UDP frame.
+    """
+
+    # Note Dot1Q.id is really CFI
+    if (dl_vlan_enable):
+        pkt = scapy.Ether(dst=eth_dst, src=eth_src)/ \
+            scapy.Dot1Q(prio=vlan_pcp, id=dl_vlan_cfi, vlan=vlan_vid)
+    else:
+        pkt = scapy.Ether(dst=eth_dst, src=eth_src)
+
+    #add MPLS header
+    for i in range(len(label)):
+        l,c,s,t=label[i]
+        pkt = pkt/scapy.MPLS(label=l, cos=c, s=s, ttl=t)
+
+    #add innder payload
+    if inner_payload!=None:
+        pkt=pkt/inner_payload
+
+    return pkt
+
+def simple_udpv6_packet(pktlen=100,
+                        eth_dst='00:01:02:03:04:05',
+                        eth_src='00:06:07:08:09:0a',
+                        dl_vlan_enable=False,
+                        vlan_vid=0,
+                        vlan_pcp=0,
+                        ipv6_src='2001:db8:85a3::8a2e:370:7334',
+                        ipv6_dst='2001:db8:85a3::8a2e:370:7335',
+                        ipv6_tc=0,
+                        ipv6_hlim=64,
+                        ipv6_fl=0,
+                        udp_sport=1234,
+                        udp_dport=80):
+    """
+    Return a simple IPv6/UDP packet
+
+    Supports a few parameters:
+    @param len Length of packet in bytes w/o CRC
+    @param eth_dst Destination MAC
+    @param eth_src Source MAC
+    @param dl_vlan_enable True if the packet is with vlan, False otherwise
+    @param vlan_vid VLAN ID
+    @param vlan_pcp VLAN priority
+    @param ipv6_src IPv6 source
+    @param ipv6_dst IPv6 destination
+    @param ipv6_tc IPv6 traffic class
+    @param ipv6_ttl IPv6 hop limit
+    @param ipv6_fl IPv6 flow label
+    @param udp_dport UDP destination port
+    @param udp_sport UDP source port
+
+    Generates a simple UDP request. Users shouldn't assume anything about this
+    packet other than that it is a valid ethernet/IPv6/UDP frame.
+    """
+
+    if MINSIZE > pktlen:
+        pktlen = MINSIZE
+
+    pkt = scapy.Ether(dst=eth_dst, src=eth_src)
+    if dl_vlan_enable or vlan_vid or vlan_pcp:
+        pkt /= scapy.Dot1Q(vlan=vlan_vid, prio=vlan_pcp)
+    pkt /= scapy.IPv6(src=ipv6_src, dst=ipv6_dst, fl=ipv6_fl, tc=ipv6_tc, hlim=ipv6_hlim)
+    pkt /= scapy.UDP(sport=udp_sport, dport=udp_dport)
+    pkt /= ("D" * (pktlen - len(pkt)))
+
+    return pkt
+
+def simple_icmp_packet(pktlen=60,
+                      eth_dst='00:01:02:03:04:05',
+                      eth_src='00:06:07:08:09:0a',
+                      dl_vlan_enable=False,
+                      vlan_vid=0,
+                      vlan_pcp=0,
+                      ip_src='192.168.0.1',
+                      ip_dst='192.168.0.2',
+                      ip_tos=0,
+                      ip_ttl=64,
+                      ip_id=1,
+                      icmp_type=8,
+                      icmp_code=0,
+                      icmp_data=''):
+    """
+    Return a simple ICMP packet
+
+    Supports a few parameters:
+    @param len Length of packet in bytes w/o CRC
+    @param eth_dst Destinatino MAC
+    @param eth_src Source MAC
+    @param dl_vlan_enable True if the packet is with vlan, False otherwise
+    @param vlan_vid VLAN ID
+    @param vlan_pcp VLAN priority
+    @param ip_src IP source
+    @param ip_dst IP destination
+    @param ip_tos IP ToS
+    @param ip_ttl IP TTL
+    @param ip_id IP Identification
+    @param icmp_type ICMP type
+    @param icmp_code ICMP code
+    @param icmp_data ICMP data
+
+    Generates a simple ICMP ECHO REQUEST.  Users
+    shouldn't assume anything about this packet other than that
+    it is a valid ethernet/ICMP frame.
+    """
+
+    if MINSIZE > pktlen:
+        pktlen = MINSIZE
+
+    if (dl_vlan_enable):
+        pkt = scapy.Ether(dst=eth_dst, src=eth_src)/ \
+            scapy.Dot1Q(prio=vlan_pcp, id=0, vlan=vlan_vid)/ \
+            scapy.IP(src=ip_src, dst=ip_dst, ttl=ip_ttl, tos=ip_tos, id=ip_id)/ \
+            scapy.ICMP(type=icmp_type, code=icmp_code)/ icmp_data
+    else:
+        pkt = scapy.Ether(dst=eth_dst, src=eth_src)/ \
+            scapy.IP(src=ip_src, dst=ip_dst, ttl=ip_ttl, tos=ip_tos, id=ip_id)/ \
+            scapy.ICMP(type=icmp_type, code=icmp_code)/ icmp_data
+
+    pkt = pkt/("0" * (pktlen - len(pkt)))
+
+    return pkt
+
+def simple_icmpv6_packet(pktlen=100,
+                         eth_dst='00:01:02:03:04:05',
+                         eth_src='00:06:07:08:09:0a',
+                         dl_vlan_enable=False,
+                         vlan_vid=0,
+                         vlan_pcp=0,
+                         ipv6_src='2001:db8:85a3::8a2e:370:7334',
+                         ipv6_dst='2001:db8:85a3::8a2e:370:7335',
+                         ipv6_tc=0,
+                         ipv6_hlim=64,
+                         ipv6_fl=0,
+                         icmp_type=8,
+                         icmp_code=0):
+    """
+    Return a simple ICMPv6 packet
+
+    Supports a few parameters:
+    @param len Length of packet in bytes w/o CRC
+    @param eth_dst Destination MAC
+    @param eth_src Source MAC
+    @param dl_vlan_enable True if the packet is with vlan, False otherwise
+    @param vlan_vid VLAN ID
+    @param vlan_pcp VLAN priority
+    @param ipv6_src IPv6 source
+    @param ipv6_dst IPv6 destination
+    @param ipv6_tc IPv6 traffic class
+    @param ipv6_ttl IPv6 hop limit
+    @param ipv6_fl IPv6 flow label
+    @param icmp_type ICMP type
+    @param icmp_code ICMP code
+
+    Generates a simple ICMP ECHO REQUEST. Users shouldn't assume anything
+    about this packet other than that it is a valid ethernet/IPv6/ICMP frame.
+    """
+
+    if MINSIZE > pktlen:
+        pktlen = MINSIZE
+
+    pkt = scapy.Ether(dst=eth_dst, src=eth_src)
+    if dl_vlan_enable or vlan_vid or vlan_pcp:
+        pkt /= scapy.Dot1Q(vlan=vlan_vid, prio=vlan_pcp)
+    pkt /= scapy.IPv6(src=ipv6_src, dst=ipv6_dst, fl=ipv6_fl, tc=ipv6_tc, hlim=ipv6_hlim)
+    pkt /= scapy.ICMPv6Unknown(type=icmp_type, code=icmp_code)
+    pkt /= ("D" * (pktlen - len(pkt)))
+
+    return pkt
+
+def simple_arp_packet(pktlen=60,
+                      eth_dst='ff:ff:ff:ff:ff:ff',
+                      eth_src='00:06:07:08:09:0a',
+                      vlan_vid=0,
+                      vlan_pcp=0,
+                      arp_op=1,
+                      ip_snd='192.168.0.1',
+                      ip_tgt='192.168.0.2',
+                      hw_snd='00:06:07:08:09:0a',
+                      hw_tgt='00:00:00:00:00:00',
+                      ):
+    """
+    Return a simple ARP packet
+
+    Supports a few parameters:
+    @param len Length of packet in bytes w/o CRC
+    @param eth_dst Destinatino MAC
+    @param eth_src Source MAC
+    @param arp_op Operation (1=request, 2=reply)
+    @param ip_snd Sender IP
+    @param ip_tgt Target IP
+    @param hw_snd Sender hardware address
+    @param hw_tgt Target hardware address
+
+    Generates a simple ARP REQUEST.  Users
+    shouldn't assume anything about this packet other than that
+    it is a valid ethernet/ARP frame.
+    """
+
+    if MINSIZE > pktlen:
+        pktlen = MINSIZE
+
+    pkt = scapy.Ether(dst=eth_dst, src=eth_src)
+    if vlan_vid or vlan_pcp:
+        pkt /= scapy.Dot1Q(vlan=vlan_vid, prio=vlan_pcp)
+    pkt /= scapy.ARP(hwsrc=hw_snd, hwdst=hw_tgt, pdst=ip_tgt, psrc=ip_snd, op=arp_op)
+
+    pkt = pkt/("\0" * (pktlen - len(pkt)))
+
+    return pkt
+
+def simple_eth_packet(pktlen=60,
+                      eth_dst='00:01:02:03:04:05',
+                      eth_src='00:06:07:08:09:0a',
+                      eth_type=0x88cc):
+
+    if MINSIZE > pktlen:
+        pktlen = MINSIZE
+
+    pkt = scapy.Ether(dst=eth_dst, src=eth_src, type=eth_type)
+
+    pkt = pkt/("0" * (pktlen - len(pkt)))
+
+    return pkt
+
+def qinq_tcp_packet(pktlen=100,
+                    eth_dst='00:01:02:03:04:05',
+                    eth_src='00:06:07:08:09:0a',
+                    dl_vlan_outer=20,
+                    dl_vlan_pcp_outer=0,
+                    dl_vlan_cfi_outer=0,
+                    vlan_vid=10,
+                    vlan_pcp=0,
+                    dl_vlan_cfi=0,
+                    ip_src='192.168.0.1',
+                    ip_dst='192.168.0.2',
+                    ip_tos=0,
+                    ip_ttl=64,
+                    tcp_sport=1234,
+                    tcp_dport=80,
+                    ip_ihl=None,
+                    ip_options=False
+                    ):
+    """
+    Return a doubly tagged dataplane TCP packet
+
+    Supports a few parameters:
+    @param len Length of packet in bytes w/o CRC
+    @param eth_dst Destinatino MAC
+    @param eth_src Source MAC
+    @param dl_vlan_outer Outer VLAN ID
+    @param dl_vlan_pcp_outer Outer VLAN priority
+    @param dl_vlan_cfi_outer Outer VLAN cfi bit
+    @param vlan_vid Inner VLAN ID
+    @param vlan_pcp VLAN priority
+    @param dl_vlan_cfi VLAN cfi bit
+    @param ip_src IP source
+    @param ip_dst IP destination
+    @param ip_tos IP ToS
+    @param tcp_dport TCP destination port
+    @param ip_sport TCP source port
+
+    Generates a TCP request.  Users
+    shouldn't assume anything about this packet other than that
+    it is a valid ethernet/IP/TCP frame.
+    """
+
+    if MINSIZE > pktlen:
+        pktlen = MINSIZE
+
+    # Note Dot1Q.id is really CFI
+    pkt = scapy.Ether(dst=eth_dst, src=eth_src)/ \
+          scapy.Dot1Q(prio=dl_vlan_pcp_outer, id=dl_vlan_cfi_outer, vlan=dl_vlan_outer)/ \
+          scapy.Dot1Q(prio=vlan_pcp, id=dl_vlan_cfi, vlan=vlan_vid)/ \
+          scapy.IP(src=ip_src, dst=ip_dst, tos=ip_tos, ttl=ip_ttl, ihl=ip_ihl)/ \
+          scapy.TCP(sport=tcp_sport, dport=tcp_dport)
+
+    pkt = pkt/("D" * (pktlen - len(pkt)))
+
+    return pkt
+
+def qinq_packet(pktlen=100,
+                type=0x0800,
+                eth_dst='00:01:02:03:04:05',
+                eth_src='00:06:07:08:09:0a',
+                dl_vlan_outer=20,
+                dl_vlan_pcp_outer=0,
+                dl_vlan_cfi_outer=0,
+                vlan_vid=10,
+                vlan_pcp=0,
+                dl_vlan_cfi=0,
+                ):
+    """
+    Return a doubly tagged dataplane qinq packet
+
+    Supports a few parameters:
+    @param len Length of packet in bytes w/o CRC
+    @param type ethernet type
+    @param eth_dst Destinatino MAC
+    @param eth_src Source MAC
+    @param dl_vlan_outer Outer VLAN ID
+    @param dl_vlan_pcp_outer Outer VLAN priority
+    @param dl_vlan_cfi_outer Outer VLAN cfi bit
+    @param vlan_vid Inner VLAN ID
+    @param vlan_pcp VLAN priority
+    @param dl_vlan_cfi VLAN cfi bit
+
+    Generates a qinq request.
+    """
+
+    if MINSIZE > pktlen:
+        pktlen = MINSIZE
+
+    # Note Dot1Q.id is really CFI
+    pkt = scapy.Ether(dst=eth_dst, src=eth_src, type=type) / \
+          scapy.Dot1Q(prio=dl_vlan_pcp_outer, id=dl_vlan_cfi_outer, vlan=dl_vlan_outer) / \
+          scapy.Dot1Q(prio=vlan_pcp, id=dl_vlan_cfi, vlan=vlan_vid) / \
+          scapy.IP()
+
+    pkt = pkt / ("D" * (pktlen - len(pkt)))
+    return pkt
+
+def simple_ether_packet_two_vlan(pktlen=100,
+                                 eth_dst='00:01:02:03:04:05',
+                                 eth_src='00:06:07:08:09:0a',
+                                 out_dl_vlan_enable=True,
+                                 in_dl_vlan_enable=True,
+                                 out_vlan_vid=100,
+                                 out_vlan_pcp=0,
+                                 out_vlan_tpid=0x8100,
+                                 out_dl_vlan_cfi=0,
+                                 in_vlan_vid=100,
+                                 in_vlan_pcp=0,
+                                 in_vlan_tpid=0x0800,
+                                 in_dl_vlan_cfi=0):
+    """
+    Return a simple dataplane ether packet
+
+    Supports a few parameters:
+    @param len Length of packet in bytes w/o CRC
+    @param eth_dst Destinatino MAC
+    @param eth_src Source MAC
+    @param dl_vlan_enable True if the packet is with vlan, False otherwise
+    @param vlan_vid VLAN ID
+    @param vlan_pcp VLAN priority
+    """
+
+    if MINSIZE > pktlen:
+        pktlen = MINSIZE
+
+    if (out_dl_vlan_enable and in_dl_vlan_enable):
+        pkt = scapy.Ether(dst=eth_dst, src=eth_src, type=out_vlan_tpid) / \
+              scapy.Dot1Q(prio=out_vlan_pcp, id=out_dl_vlan_cfi, vlan=out_vlan_vid)
+        pkt = pkt / scapy.Dot1Q(prio=in_vlan_pcp, id=in_dl_vlan_cfi, vlan=in_vlan_vid, type=in_vlan_tpid)
+
+    elif (out_dl_vlan_enable and (not in_dl_vlan_enable)):
+        pkt = scapy.Ether(dst=eth_dst, src=eth_src) / \
+              scapy.Dot1Q(prio=out_vlan_pcp, id=out_dl_vlan_cfi, vlan=out_vlan_vid)
+
+    elif ((not out_dl_vlan_enable) and in_dl_vlan_enable):
+        assert (0)  # shall not have this case
+    else:
+        pkt = scapy.Ether(dst=eth_dst, src=eth_src)
+
+    pkt = pkt / ("D" * (pktlen - len(pkt)))
+    return pkt
+
+
+def do_barrier(ctrl, timeout=-1):
+    """
+    Do a barrier command
+    Return 0 on success, -1 on error
+    """
+    b = ofp.message.barrier_request()
+    (resp, pkt) = ctrl.transact(b, timeout=timeout)
+    if resp is None:
+        raise AssertionError("barrier failed")
+    # We'll trust the transaction processing in the controller that xid matched
+    return 0 # for backwards compatibility
+
+def port_config_get(controller, port_no):
+    """
+    Get a port's configuration
+
+    Gets the switch feature configuration and grabs one port's
+    configuration
+
+    @returns (hwaddr, config, advert) The hwaddress, configuration and
+    advertised values
+    """
+
+    if ofp.OFP_VERSION <= 3:
+        request = ofp.message.features_request()
+        reply, _ = controller.transact(request)
+        if reply is None:
+            logging.warn("Get feature request failed")
+            return None, None, None
+        logging.debug(reply.show())
+        ports = reply.ports
+    else:
+        request = ofp.message.port_desc_stats_request()
+        # TODO do multipart correctly
+        reply, _ = controller.transact(request)
+        if reply is None:
+            logging.warn("Port desc stats request failed")
+            return None, None, None
+        logging.debug(reply.show())
+        ports = reply.entries
+
+    for port in ports:
+        if port.port_no == port_no:
+            return (port.hw_addr, port.config, port.advertised)
+
+    logging.warn("Did not find port number for port config")
+    return None, None, None
+
+def port_config_set(controller, port_no, config, mask):
+    """
+    Set the port configuration according the given parameters
+
+    Gets the switch feature configuration and updates one port's
+    configuration value according to config and mask
+    """
+    logging.info("Setting port " + str(port_no) + " to config " + str(config))
+
+    hw_addr, _, _ = port_config_get(controller, port_no)
+
+    mod = ofp.message.port_mod()
+    mod.port_no = port_no
+    if hw_addr != None:
+        mod.hw_addr = hw_addr
+    mod.config = config
+    mod.mask = mask
+    mod.advertise = 0 # No change
+    controller.message_send(mod)
+    return 0
+
+def receive_pkt_check(dp, pkt, yes_ports, no_ports, assert_if):
+    """
+    Check for proper receive packets across all ports
+    @param dp The dataplane object
+    @param pkt Expected packet; may be None if yes_ports is empty
+    @param yes_ports Set or list of ports that should recieve packet
+    @param no_ports Set or list of ports that should not receive packet
+    @param assert_if Object that implements assertXXX
+
+    DEPRECATED in favor in verify_packets
+    """
+
+    exp_pkt_arg = None
+    if oftest.config["relax"]:
+        exp_pkt_arg = pkt
+
+    for ofport in yes_ports:
+        logging.debug("Checking for pkt on port " + str(ofport))
+        (rcv_port, rcv_pkt, pkt_time) = dp.poll(
+            port_number=ofport, exp_pkt=exp_pkt_arg)
+        assert_if.assertTrue(rcv_pkt is not None,
+                             "Did not receive pkt on " + str(ofport))
+        if not oftest.dataplane.match_exp_pkt(pkt, rcv_pkt):
+            logging.debug("Expected %s" % format_packet(pkt))
+            logging.debug("Received %s" % format_packet(rcv_pkt))
+        assert_if.assertTrue(oftest.dataplane.match_exp_pkt(pkt, rcv_pkt),
+                             "Received packet does not match expected packet " +
+                             "on port " + str(ofport))
+    if len(no_ports) > 0:
+        time.sleep(oftest.ofutils.default_negative_timeout)
+    for ofport in no_ports:
+        logging.debug("Negative check for pkt on port " + str(ofport))
+        (rcv_port, rcv_pkt, pkt_time) = dp.poll(
+            port_number=ofport, timeout=0, exp_pkt=exp_pkt_arg)
+        assert_if.assertTrue(rcv_pkt is None,
+                             "Unexpected pkt on port " + str(ofport))
+
+
+def receive_pkt_verify(parent, egr_ports, exp_pkt, ing_port):
+    """
+    Receive a packet and verify it matches an expected value
+    @param egr_port A single port or list of ports
+
+    parent must implement dataplane, assertTrue and assertEqual
+
+    DEPRECATED in favor in verify_packets
+    """
+    exp_pkt_arg = None
+    if oftest.config["relax"]:
+        exp_pkt_arg = exp_pkt
+
+    if type(egr_ports) == type([]):
+        egr_port_list = egr_ports
+    else:
+        egr_port_list = [egr_ports]
+
+    # Expect a packet from each port on egr port list
+    for egr_port in egr_port_list:
+        check_port = egr_port
+        if egr_port == ofp.OFPP_IN_PORT:
+            check_port = ing_port
+        (rcv_port, rcv_pkt, pkt_time) = parent.dataplane.poll(
+            port_number=check_port, exp_pkt=exp_pkt_arg)
+
+        if rcv_pkt is None:
+            logging.error("ERROR: No packet received from " +
+                                str(check_port))
+
+        parent.assertTrue(rcv_pkt is not None,
+                          "Did not receive packet port " + str(check_port))
+        logging.debug("Packet len " + str(len(rcv_pkt)) + " in on " +
+                            str(rcv_port))
+
+        if str(exp_pkt) != str(rcv_pkt):
+            logging.error("ERROR: Packet match failed.")
+            logging.debug("Expected len " + str(len(exp_pkt)) + ": "
+                                + str(exp_pkt).encode('hex'))
+            logging.debug("Received len " + str(len(rcv_pkt)) + ": "
+                                + str(rcv_pkt).encode('hex'))
+            logging.debug("Expected packet: " + inspect_packet(scapy.Ether(str(exp_pkt))))
+            logging.debug("Received packet: " + inspect_packet(scapy.Ether(str(rcv_pkt))))
+        parent.assertEqual(str(exp_pkt), str(rcv_pkt),
+                           "Packet match error on port " + str(check_port))
+
+def match_verify(parent, req_match, res_match):
+    """
+    Verify flow matches agree; if they disagree, report where
+
+    parent must implement assertEqual
+    Use str() to ensure content is compared and not pointers
+    """
+
+    parent.assertEqual(req_match.wildcards, res_match.wildcards,
+                       'Match failed: wildcards: ' + hex(req_match.wildcards) +
+                       " != " + hex(res_match.wildcards))
+    parent.assertEqual(req_match.in_port, res_match.in_port,
+                       'Match failed: in_port: ' + str(req_match.in_port) +
+                       " != " + str(res_match.in_port))
+    parent.assertEqual(str(req_match.eth_src), str(res_match.eth_src),
+                       'Match failed: eth_src: ' + str(req_match.eth_src) +
+                       " != " + str(res_match.eth_src))
+    parent.assertEqual(str(req_match.eth_dst), str(res_match.eth_dst),
+                       'Match failed: eth_dst: ' + str(req_match.eth_dst) +
+                       " != " + str(res_match.eth_dst))
+    parent.assertEqual(req_match.vlan_vid, res_match.vlan_vid,
+                       'Match failed: vlan_vid: ' + str(req_match.vlan_vid) +
+                       " != " + str(res_match.vlan_vid))
+    parent.assertEqual(req_match.vlan_pcp, res_match.vlan_pcp,
+                       'Match failed: vlan_pcp: ' +
+                       str(req_match.vlan_pcp) + " != " +
+                       str(res_match.vlan_pcp))
+    parent.assertEqual(req_match.eth_type, res_match.eth_type,
+                       'Match failed: eth_type: ' + str(req_match.eth_type) +
+                       " != " + str(res_match.eth_type))
+
+    if (not(req_match.wildcards & ofp.OFPFW_DL_TYPE)
+        and (req_match.eth_type == IP_ETHERTYPE)):
+        parent.assertEqual(req_match.ip_dscp, res_match.ip_dscp,
+                           'Match failed: ip_dscp: ' + str(req_match.ip_dscp) +
+                           " != " + str(res_match.ip_dscp))
+        parent.assertEqual(req_match.ip_proto, res_match.ip_proto,
+                           'Match failed: ip_proto: ' + str(req_match.ip_proto) +
+                           " != " + str(res_match.ip_proto))
+        parent.assertEqual(req_match.ipv4_src, res_match.ipv4_src,
+                           'Match failed: ipv4_src: ' + str(req_match.ipv4_src) +
+                           " != " + str(res_match.ipv4_src))
+        parent.assertEqual(req_match.ipv4_dst, res_match.ipv4_dst,
+                           'Match failed: ipv4_dst: ' + str(req_match.ipv4_dst) +
+                           " != " + str(res_match.ipv4_dst))
+
+        if (not(req_match.wildcards & ofp.OFPFW_NW_PROTO)
+            and ((req_match.ip_proto == TCP_PROTOCOL)
+                 or (req_match.ip_proto == UDP_PROTOCOL))):
+            parent.assertEqual(req_match.tcp_src, res_match.tcp_src,
+                               'Match failed: tcp_src: ' +
+                               str(req_match.tcp_src) +
+                               " != " + str(res_match.tcp_src))
+            parent.assertEqual(req_match.tcp_dst, res_match.tcp_dst,
+                               'Match failed: tcp_dst: ' +
+                               str(req_match.tcp_dst) +
+                               " != " + str(res_match.tcp_dst))
+
+def packet_to_flow_match(parent, packet):
+    match = oftest.parse.packet_to_flow_match(packet)
+    if ofp.OFP_VERSION in [1, 2]:
+        match.wildcards |= required_wildcards(parent)
+    else:
+        # TODO remove incompatible OXM entries
+        pass
+    return match
+
+def flow_msg_create(parent, pkt, ing_port=None, action_list=None, wildcards=None,
+               egr_ports=None, egr_queue=None, check_expire=False, in_band=False):
+    """
+    Create a flow message
+
+    Match on packet with given wildcards.
+    See flow_match_test for other parameter descriptoins
+    @param egr_queue if not None, make the output an enqueue action
+    @param in_band if True, do not wildcard ingress port
+    @param egr_ports None (drop), single port or list of ports
+    """
+    match = oftest.parse.packet_to_flow_match(pkt)
+    parent.assertTrue(match is not None, "Flow match from pkt failed")
+    if wildcards is None:
+        wildcards = required_wildcards(parent)
+    if in_band:
+        wildcards &= ~ofp.OFPFW_IN_PORT
+    match.wildcards = wildcards
+    match.in_port = ing_port
+
+    if type(egr_ports) == type([]):
+        egr_port_list = egr_ports
+    else:
+        egr_port_list = [egr_ports]
+
+    request = ofp.message.flow_add()
+    request.match = match
+    request.buffer_id = 0xffffffff
+    if check_expire:
+        request.flags |= ofp.OFPFF_SEND_FLOW_REM
+        request.hard_timeout = 1
+
+    if ofp.OFP_VERSION == 1:
+        actions = request.actions
+    else:
+        actions = []
+        request.instructions.append(ofp.instruction.apply_actions(actions))
+
+    if action_list is not None:
+        actions.extend(action_list)
+
+    # Set up output/enqueue action if directed
+    if egr_queue is not None:
+        parent.assertTrue(egr_ports is not None, "Egress port not set")
+        act = ofp.action.enqueue()
+        for egr_port in egr_port_list:
+            act.port = egr_port
+            act.queue_id = egr_queue
+            actions.append(act)
+    elif egr_ports is not None:
+        for egr_port in egr_port_list:
+            act = ofp.action.output()
+            act.port = egr_port
+            actions.append(act)
+
+    logging.debug(request.show())
+
+    return request
+
+def flow_msg_install(parent, request, clear_table_override=None):
+    """
+    Install a flow mod message in the switch
+
+    @param parent Must implement controller, assertEqual, assertTrue
+    @param request The request, all set to go
+    @param clear_table If true, clear the flow table before installing
+    """
+
+    clear_table = test_param_get('clear_table', default=True)
+    if(clear_table_override != None):
+        clear_table = clear_table_override
+
+    if clear_table:
+        logging.debug("Clear flow table")
+        delete_all_flows(parent.controller)
+
+    logging.debug("Insert flow")
+    parent.controller.message_send(request)
+
+    do_barrier(parent.controller)
+
+def flow_match_test_port_pair(parent, ing_port, egr_ports, wildcards=None,
+                              vlan_vid=-1, pkt=None, exp_pkt=None,
+                              action_list=None):
+    """
+    Flow match test on single TCP packet
+    @param egr_ports A single port or list of ports
+
+    Run test with packet through switch from ing_port to egr_port
+    See flow_match_test for parameter descriptions
+    """
+
+    if wildcards is None:
+        wildcards = required_wildcards(parent)
+    logging.info("Pkt match test: " + str(ing_port) + " to " +
+                       str(egr_ports))
+    logging.debug("  WC: " + hex(wildcards) + " vlan: " + str(vlan_vid))
+    if pkt is None:
+        pkt = simple_tcp_packet(dl_vlan_enable=(vlan_vid >= 0), vlan_vid=vlan_vid)
+    if exp_pkt is None:
+        exp_pkt = pkt
+
+    request = flow_msg_create(parent, pkt, ing_port=ing_port,
+                              wildcards=wildcards, egr_ports=egr_ports,
+                              action_list=action_list)
+
+    flow_msg_install(parent, request)
+
+    logging.debug("Send packet: " + str(ing_port) + " to " +
+                        str(egr_ports))
+    parent.dataplane.send(ing_port, str(pkt))
+
+    exp_ports = [ing_port if port == ofp.OFPP_IN_PORT else port for port in egr_ports]
+    verify_packets(parent, exp_pkt, exp_ports)
+
+def flow_match_test_pktout(parent, ing_port, egr_ports,
+                           vlan_vid=-1, pkt=None, exp_pkt=None,
+                           action_list=None):
+    """
+    Packet-out test on single TCP packet
+    @param egr_ports A single port or list of ports
+
+    Run test sending packet-out to egr_ports. The goal is to test the actions
+    taken on the packet, not the matching which is of course irrelevant.
+    See flow_match_test for parameter descriptions
+    """
+
+    if pkt is None:
+        pkt = simple_tcp_packet(dl_vlan_enable=(vlan_vid >= 0), vlan_vid=vlan_vid)
+    if exp_pkt is None:
+        exp_pkt = pkt
+
+    msg = ofp.message.packet_out()
+    msg.in_port = ing_port
+    msg.buffer_id = 0xffffffff
+    msg.data = str(pkt)
+    if action_list is not None:
+        for act in action_list:
+            msg.actions.append(act)
+
+    # Set up output action
+    if egr_ports is not None:
+        for egr_port in egr_ports:
+            act = ofp.action.output()
+            act.port = egr_port
+            msg.actions.append(act)
+
+    logging.debug(msg.show())
+    parent.controller.message_send(msg)
+
+    exp_ports = [ing_port if port == ofp.OFPP_IN_PORT else port for port in egr_ports]
+    verify_packets(parent, exp_pkt, exp_ports)
+
+def get_egr_list(parent, of_ports, how_many, exclude_list=[]):
+    """
+    Generate a list of ports avoiding those in the exclude list
+    @param parent Supplies logging
+    @param of_ports List of OF port numbers
+    @param how_many Number of ports to be added to the list
+    @param exclude_list List of ports not to be used
+    @returns An empty list if unable to find enough ports
+    """
+
+    if how_many == 0:
+        return []
+
+    count = 0
+    egr_ports = []
+    for egr_idx in range(len(of_ports)):
+        if of_ports[egr_idx] not in exclude_list:
+            egr_ports.append(of_ports[egr_idx])
+            count += 1
+            if count >= how_many:
+                return egr_ports
+    logging.debug("Could not generate enough egress ports for test")
+    return []
+
+def flow_match_test(parent, port_map, wildcards=None, vlan_vid=-1, pkt=None,
+                    exp_pkt=None, action_list=None,
+                    max_test=0, egr_count=1, ing_port=False):
+    """
+    Run flow_match_test_port_pair on all port pairs and packet-out
+
+    @param max_test If > 0 no more than this number of tests are executed.
+    @param parent Must implement controller, dataplane, assertTrue, assertEqual
+    and logging
+    @param pkt If not None, use this packet for ingress
+    @param wildcards For flow match entry
+    @param vlan_vid If not -1, and pkt is None, create a pkt w/ VLAN tag
+    @param exp_pkt If not None, use this as the expected output pkt; els use pkt
+    @param action_list Additional actions to add to flow mod
+    @param egr_count Number of egress ports; -1 means get from config w/ dflt 2
+    """
+    if wildcards is None:
+        wildcards = required_wildcards(parent)
+    of_ports = port_map.keys()
+    of_ports.sort()
+    parent.assertTrue(len(of_ports) > 1, "Not enough ports for test")
+    test_count = 0
+
+    if egr_count == -1:
+        egr_count = test_param_get('egr_count', default=2)
+
+    for ing_idx in range(len(of_ports)):
+        ingress_port = of_ports[ing_idx]
+        egr_ports = get_egr_list(parent, of_ports, egr_count,
+                                 exclude_list=[ingress_port])
+        if ing_port:
+            egr_ports.append(ofp.OFPP_IN_PORT)
+        if len(egr_ports) == 0:
+            parent.assertTrue(0, "Failed to generate egress port list")
+
+        flow_match_test_port_pair(parent, ingress_port, egr_ports,
+                                  wildcards=wildcards, vlan_vid=vlan_vid,
+                                  pkt=pkt, exp_pkt=exp_pkt,
+                                  action_list=action_list)
+        test_count += 1
+        if (max_test > 0) and (test_count > max_test):
+            logging.info("Ran " + str(test_count) + " tests; exiting")
+            break
+
+    if not test_param_get('pktout_actions', default=True):
+        return
+
+    ingress_port = of_ports[0]
+    egr_ports = get_egr_list(parent, of_ports, egr_count,
+                             exclude_list=[ingress_port])
+    if ing_port:
+        egr_ports.append(ofp.OFPP_IN_PORT)
+    flow_match_test_pktout(parent, ingress_port, egr_ports,
+                           vlan_vid=vlan_vid,
+                           pkt=pkt, exp_pkt=exp_pkt,
+                           action_list=action_list)
+
+def test_param_get(key, default=None):
+    """
+    Return value passed via test-params if present
+
+    @param key The lookup key
+    @param default Default value to use if not found
+
+    If the pair 'key=val' appeared in the string passed to --test-params
+    on the command line, return val (as interpreted by exec).  Otherwise
+    return default value.
+
+    WARNING: TEST PARAMETERS MUST BE PYTHON IDENTIFIERS;
+    eg egr_count, not egr-count.
+    """
+    try:
+        exec oftest.config["test_params"]
+    except:
+        return default
+
+    try:
+        return eval(str(key))
+    except:
+        return default
+
+def action_generate(parent, field_to_mod, mod_field_vals):
+    """
+    Create an action to modify the field indicated in field_to_mod
+
+    @param parent Must implement, assertTrue
+    @param field_to_mod The field to modify as a string name
+    @param mod_field_vals Hash of values to use for modified values
+    """
+
+    act = None
+
+    if field_to_mod in ['pktlen']:
+        return None
+
+    if field_to_mod == 'eth_dst':
+        act = ofp.action.set_dl_dst()
+        act.dl_addr = oftest.parse.parse_mac(mod_field_vals['eth_dst'])
+    elif field_to_mod == 'eth_src':
+        act = ofp.action.set_dl_src()
+        act.dl_addr = oftest.parse.parse_mac(mod_field_vals['eth_src'])
+    elif field_to_mod == 'dl_vlan_enable':
+        if not mod_field_vals['dl_vlan_enable']: # Strip VLAN tag
+            act = ofp.action.strip_vlan()
+        # Add VLAN tag is handled by vlan_vid field
+        # Will return None in this case
+    elif field_to_mod == 'vlan_vid':
+        act = ofp.action.set_vlan_vid()
+        act.vlan_vid = mod_field_vals['vlan_vid']
+    elif field_to_mod == 'vlan_pcp':
+        act = ofp.action.set_vlan_pcp()
+        act.vlan_pcp = mod_field_vals['vlan_pcp']
+    elif field_to_mod == 'ip_src':
+        act = ofp.action.set_nw_src()
+        act.nw_addr = oftest.parse.parse_ip(mod_field_vals['ip_src'])
+    elif field_to_mod == 'ip_dst':
+        act = ofp.action.set_nw_dst()
+        act.nw_addr = oftest.parse.parse_ip(mod_field_vals['ip_dst'])
+    elif field_to_mod == 'ip_tos':
+        act = ofp.action.set_nw_tos()
+        act.nw_tos = mod_field_vals['ip_tos']
+    elif field_to_mod == 'tcp_sport':
+        act = ofp.action.set_tp_src()
+        act.tp_port = mod_field_vals['tcp_sport']
+    elif field_to_mod == 'tcp_dport':
+        act = ofp.action.set_tp_dst()
+        act.tp_port = mod_field_vals['tcp_dport']
+    elif field_to_mod == 'udp_sport':
+        act = ofp.action.set_tp_src()
+        act.tp_port = mod_field_vals['udp_sport']
+    elif field_to_mod == 'udp_dport':
+        act = ofp.action.set_tp_dst()
+        act.tp_port = mod_field_vals['udp_dport']
+    else:
+        parent.assertTrue(0, "Unknown field to modify: " + str(field_to_mod))
+
+    return act
+
+def pkt_action_setup(parent, start_field_vals={}, mod_field_vals={},
+                     mod_fields=[], tp="tcp", check_test_params=False):
+    """
+    Set up the ingress and expected packet and action list for a test
+
+    @param parent Must implement assertTrue
+    @param start_field_values Field values to use for ingress packet (optional)
+    @param mod_field_values Field values to use for modified packet (optional)
+    @param mod_fields The list of fields to be modified by the switch in the test.
+    @params check_test_params If True, will check the parameters vid, add_vlan
+    and strip_vlan from the command line.
+
+    Returns a triple:  pkt-to-send, expected-pkt, action-list
+    """
+
+    new_actions = []
+
+    base_pkt_params = {}
+    base_pkt_params['pktlen'] = 100
+    base_pkt_params['eth_dst'] = '00:DE:F0:12:34:56'
+    base_pkt_params['eth_src'] = '00:23:45:67:89:AB'
+    base_pkt_params['dl_vlan_enable'] = False
+    base_pkt_params['vlan_vid'] = 2
+    base_pkt_params['vlan_pcp'] = 0
+    base_pkt_params['ip_src'] = '192.168.0.1'
+    base_pkt_params['ip_dst'] = '192.168.0.2'
+    base_pkt_params['ip_tos'] = 0
+    if tp == "tcp":
+        base_pkt_params['tcp_sport'] = 1234
+        base_pkt_params['tcp_dport'] = 80
+    elif tp == "udp":
+        base_pkt_params['udp_sport'] = 1234
+        base_pkt_params['udp_dport'] = 80
+    for keyname in start_field_vals.keys():
+        base_pkt_params[keyname] = start_field_vals[keyname]
+
+    mod_pkt_params = {}
+    mod_pkt_params['pktlen'] = 100
+    mod_pkt_params['eth_dst'] = '00:21:0F:ED:CB:A9'
+    mod_pkt_params['eth_src'] = '00:ED:CB:A9:87:65'
+    mod_pkt_params['dl_vlan_enable'] = False
+    mod_pkt_params['vlan_vid'] = 3
+    mod_pkt_params['vlan_pcp'] = 7
+    mod_pkt_params['ip_src'] = '10.20.30.40'
+    mod_pkt_params['ip_dst'] = '50.60.70.80'
+    mod_pkt_params['ip_tos'] = 0xf0
+    if tp == "tcp":
+        mod_pkt_params['tcp_sport'] = 4321
+        mod_pkt_params['tcp_dport'] = 8765
+    elif tp == "udp":
+        mod_pkt_params['udp_sport'] = 4321
+        mod_pkt_params['udp_dport'] = 8765
+    for keyname in mod_field_vals.keys():
+        mod_pkt_params[keyname] = mod_field_vals[keyname]
+
+    # Check for test param modifications
+    strip = False
+    if check_test_params:
+        add_vlan = test_param_get('add_vlan')
+        strip_vlan = test_param_get('strip_vlan')
+        vid = test_param_get('vid')
+
+        if add_vlan and strip_vlan:
+            parent.assertTrue(0, "Add and strip VLAN both specified")
+
+        if vid:
+            base_pkt_params['dl_vlan_enable'] = True
+            base_pkt_params['vlan_vid'] = vid
+            if 'vlan_vid' in mod_fields:
+                mod_pkt_params['vlan_vid'] = vid + 1
+
+        if add_vlan:
+            base_pkt_params['dl_vlan_enable'] = False
+            mod_pkt_params['dl_vlan_enable'] = True
+            mod_pkt_params['pktlen'] = base_pkt_params['pktlen'] + 4
+            mod_fields.append('pktlen')
+            mod_fields.append('dl_vlan_enable')
+            if 'vlan_vid' not in mod_fields:
+                mod_fields.append('vlan_vid')
+        elif strip_vlan:
+            base_pkt_params['dl_vlan_enable'] = True
+            mod_pkt_params['dl_vlan_enable'] = False
+            mod_pkt_params['pktlen'] = base_pkt_params['pktlen'] - 4
+            mod_fields.append('dl_vlan_enable')
+            mod_fields.append('pktlen')
+
+    if tp == "tcp":
+        packet_builder = simple_tcp_packet
+    elif tp == "udp":
+        packet_builder = simple_udp_packet
+    else:
+        raise NotImplementedError("unknown transport protocol %s" % tp)
+
+    # Build the ingress packet
+    ingress_pkt = packet_builder(**base_pkt_params)
+
+    # Build the expected packet, modifying the indicated fields
+    for item in mod_fields:
+        base_pkt_params[item] = mod_pkt_params[item]
+        act = action_generate(parent, item, mod_pkt_params)
+        if act:
+            new_actions.append(act)
+
+    expected_pkt = packet_builder(**base_pkt_params)
+
+    return (ingress_pkt, expected_pkt, new_actions)
+
+# Generate a simple "drop" flow mod
+# If in_band is true, then only drop from first test port
+def flow_mod_gen(port_map, in_band):
+    request = ofp.message.flow_add()
+    request.match.wildcards = ofp.OFPFW_ALL
+    if in_band:
+        request.match.wildcards = ofp.OFPFW_ALL - ofp.OFPFW_IN_PORT
+        for of_port, ifname in port_map.items(): # Grab first port
+            break
+        request.match.in_port = of_port
+    request.buffer_id = 0xffffffff
+    return request
+
+def skip_message_emit(parent, s):
+    """
+    Print out a 'skipped' message to stderr
+
+    @param s The string to print out to the log file
+    """
+    global skipped_test_count
+
+    skipped_test_count += 1
+    logging.info("Skipping: " + s)
+    if oftest.config["debug"] < logging.WARNING:
+        sys.stderr.write("(skipped) ")
+    else:
+        sys.stderr.write("(S)")
+
+
+def all_stats_get(parent):
+    """
+    Get the aggregate stats for all flows in the table
+    @param parent Test instance with controller connection and assert
+    @returns dict with keys flows, packets, bytes, active (flows),
+    lookups, matched
+    """
+    stat_req = ofp.message.aggregate_stats_request()
+    stat_req.match = ofp.match()
+    stat_req.match.wildcards = ofp.OFPFW_ALL
+    stat_req.table_id = 0xff
+    stat_req.out_port = ofp.OFPP_NONE
+
+    rv = {}
+
+    (reply, pkt) = parent.controller.transact(stat_req)
+    parent.assertTrue(len(reply.entries) == 1, "Did not receive flow stats reply")
+
+    for obj in reply.entries:
+        (rv["flows"], rv["packets"], rv["bytes"]) = (obj.flow_count,
+                                                  obj.packet_count, obj.byte_count)
+        break
+
+    request = ofp.message.table_stats_request()
+    (reply , pkt) = parent.controller.transact(request)
+
+
+    (rv["active"], rv["lookups"], rv["matched"]) = (0,0,0)
+    for obj in reply.entries:
+        rv["active"] += obj.active_count
+        rv["lookups"] += obj.lookup_count
+        rv["matched"] += obj.matched_count
+
+    return rv
+
+_import_blacklist.add('FILTER')
+FILTER=''.join([(len(repr(chr(x)))==3) and chr(x) or '.'
+                for x in range(256)])
+
+def hex_dump_buffer(src, length=16):
+    """
+    Convert src to a hex dump string and return the string
+    @param src The source buffer
+    @param length The number of bytes shown in each line
+    @returns A string showing the hex dump
+    """
+    result = ["\n"]
+    for i in xrange(0, len(src), length):
+       chars = src[i:i+length]
+       hex = ' '.join(["%02x" % ord(x) for x in chars])
+       printable = ''.join(["%s" % ((ord(x) <= 127 and
+                                     FILTER[ord(x)]) or '.') for x in chars])
+       result.append("%04x  %-*s  %s\n" % (i, length*3, hex, printable))
+    return ''.join(result)
+
+def format_packet(pkt):
+    return "Packet length %d \n%s" % (len(str(pkt)),
+                                      hex_dump_buffer(str(pkt)))
+
+def inspect_packet(pkt):
+    """
+    Wrapper around scapy's show() method.
+    @returns A string showing the dissected packet.
+    """
+    from cStringIO import StringIO
+    out = None
+    backup = sys.stdout
+    try:
+        tmp = StringIO()
+        sys.stdout = tmp
+        pkt.show2()
+        out = tmp.getvalue()
+        tmp.close()
+    finally:
+        sys.stdout = backup
+    return out
+
+def nonstandard(cls):
+    """
+    Testcase decorator that marks the test as being non-standard.
+    These tests are not automatically added to the "standard" group.
+    """
+    cls._nonstandard = True
+    return cls
+
+def disabled(cls):
+    """
+    Testcase decorator that marks the test as being disabled.
+    These tests are not automatically added to the "standard" group or
+    their module's group.
+    """
+    cls._disabled = True
+    return cls
+
+def group(name):
+    """
+    Testcase decorator that adds the test to a group.
+    """
+    def fn(cls):
+        if not hasattr(cls, "_groups"):
+            cls._groups = []
+        cls._groups.append(name)
+        return cls
+    return fn
+
+def version(ver):
+    """
+    Testcase decorator that specifies which versions of OpenFlow the test
+    supports. The default is 1.0+. This decorator may only be used once.
+
+    Supported syntax:
+    1.0 -> 1.0
+    1.0,1.2,1.3 -> 1.0, 1.2, 1.3
+    1.0+ -> 1.0, 1.1, 1.2, 1.3
+    """
+    versions = parse_version(ver)
+    def fn(cls):
+        cls._versions = versions
+        return cls
+    return fn
+
+def parse_version(ver):
+    allowed_versions = ["1.0", "1.1", "1.2", "1.3"]
+    if re.match("^1\.\d+$", ver):
+        versions = set([ver])
+    elif re.match("^(1\.\d+)\+$", ver):
+        if not ver[:-1] in allowed_versions:
+            raise ValueError("invalid OpenFlow version %s" % ver[:-1])
+        versions = set()
+        if ver != "1.1+": versions.add("1.0")
+        if ver != "1.2+": versions.add("1.1")
+        if ver != "1.3+": versions.add("1.2")
+        versions.add("1.3")
+    else:
+        versions = set(ver.split(','))
+
+    for version in versions:
+        if not version in allowed_versions:
+            raise ValueError("invalid OpenFlow version %s" % version)
+
+    return versions
+
+assert(parse_version("1.0") == set(["1.0"]))
+assert(parse_version("1.0,1.2,1.3") == set(["1.0", "1.2", "1.3"]))
+assert(parse_version("1.0+") == set(["1.0", "1.1", "1.2", "1.3"]))
+
+def get_stats(test, req):
+    """
+    Retrieve a list of stats entries. Handles OFPSF_REPLY_MORE.
+    """
+    msgtype = ofp.OFPT_STATS_REPLY
+    more_flag = ofp.OFPSF_REPLY_MORE
+    stats = []
+    reply, _ = test.controller.transact(req)
+    test.assertTrue(reply is not None, "No response to stats request")
+    test.assertEquals(reply.type, msgtype, "Response had unexpected message type")
+    stats.extend(reply.entries)
+    while reply.flags & more_flag != 0:
+        reply, pkt = test.controller.poll(exp_msg=msgtype)
+        test.assertTrue(reply is not None, "No response to stats request")
+        stats.extend(reply.entries)
+    return stats
+
+def get_flow_stats(test, match, table_id=None,
+                   out_port=None, out_group=None,
+                   cookie=0, cookie_mask=0):
+    """
+    Retrieve a list of flow stats entries.
+    """
+
+    if table_id == None:
+        if ofp.OFP_VERSION <= 2:
+            table_id = 0xff
+        else:
+            table_id = ofp.OFPTT_ALL
+
+    if out_port == None:
+        if ofp.OFP_VERSION == 1:
+            out_port = ofp.OFPP_NONE
+        else:
+            out_port = ofp.OFPP_ANY
+
+    if out_group == None:
+        if ofp.OFP_VERSION > 1:
+            out_group = ofp.OFPP_ANY
+
+    req = ofp.message.flow_stats_request(match=match,
+                                         table_id=table_id,
+                                         out_port=out_port)
+    if ofp.OFP_VERSION > 1:
+        req.out_group = out_group
+        req.cookie = cookie
+        req.cookie_mask = cookie_mask
+
+    return get_stats(test, req)
+
+def get_port_stats(test, port_no):
+    """
+    Retrieve a list of port stats entries.
+    """
+    req = ofp.message.port_stats_request(port_no=port_no)
+    return get_stats(test, req)
+
+def get_queue_stats(test, port_no, queue_id):
+    """
+    Retrieve a list of queue stats entries.
+    """
+    req = ofp.message.queue_stats_request(port_no=port_no, queue_id=queue_id)
+    return get_stats(test, req)
+
+def verify_flow_stats(test, match, table_id=0xff,
+                      initial=[],
+                      pkts=None, bytes=None):
+    """
+    Verify that flow stats changed as expected.
+
+    Optionally takes an 'initial' list of stats entries, as returned by
+    get_flow_stats(). If 'initial' is not given the counters are assumed to
+    begin at 0.
+    """
+
+    def accumulate(stats):
+        pkts_acc = bytes_acc = 0
+        for stat in stats:
+            pkts_acc += stat.packet_count
+            bytes_acc += stat.byte_count
+        return (pkts_acc, bytes_acc)
+
+    pkts_before, bytes_before = accumulate(initial)
+
+    # Wait 10s for counters to update
+    pkt_diff = byte_diff = None
+    for i in range(0, 100):
+        stats = get_flow_stats(test, match, table_id=table_id)
+        pkts_after, bytes_after = accumulate(stats)
+        pkt_diff = pkts_after - pkts_before
+        byte_diff = bytes_after - bytes_before
+        if (pkts == None or pkt_diff >= pkts) and \
+           (bytes == None or byte_diff >= bytes):
+            break
+        time.sleep(0.1)
+
+    if pkts != None:
+        test.assertEquals(pkt_diff, pkts, "Flow packet counter not updated properly (expected increase of %d, got increase of %d)" % (pkts, pkt_diff))
+
+    if bytes != None:
+        test.assertTrue(byte_diff >= bytes and byte_diff <= bytes*1.1,
+                        "Flow byte counter not updated properly (expected increase of %d, got increase of %d)" % (bytes, byte_diff))
+
+def verify_port_stats(test, port,
+                      initial=[],
+                      tx_pkts=None, rx_pkts=None,
+                      tx_bytes=None, rx_bytes=None):
+    """
+    Verify that port stats changed as expected.
+
+    Optionally takes an 'initial' list of stats entries, as returned by
+    get_port_stats(). If 'initial' is not given the counters are assumed to
+    begin at 0.
+    """
+    def accumulate(stats):
+        tx_pkts_acc = rx_pkts_acc = tx_bytes_acc = rx_bytes_acc = 0
+        for stat in stats:
+            tx_pkts_acc += stat.tx_packets
+            rx_pkts_acc += stat.rx_packets
+            tx_bytes_acc += stat.tx_bytes
+            rx_bytes_acc += stat.rx_bytes
+        return (tx_pkts_acc, rx_pkts_acc, tx_bytes_acc, rx_bytes_acc)
+
+    tx_pkts_before, rx_pkts_before, \
+        tx_bytes_before, rx_bytes_before = accumulate(initial)
+
+    # Wait 10s for counters to update
+    for i in range(0, 100):
+        stats = get_port_stats(test, port)
+        tx_pkts_after, rx_pkts_after, \
+            tx_bytes_after, rx_bytes_after = accumulate(stats)
+        tx_pkts_diff = tx_pkts_after - tx_pkts_before
+        rx_pkts_diff = rx_pkts_after - rx_pkts_before
+        tx_bytes_diff = tx_bytes_after - tx_bytes_before
+        rx_bytes_diff = rx_bytes_after - rx_bytes_before
+        if (tx_pkts == None or tx_pkts <= tx_pkts_diff) and \
+           (rx_pkts == None or rx_pkts <= rx_pkts_diff) and \
+           (tx_bytes == None or tx_bytes <= tx_bytes_diff) and \
+           (rx_bytes == None or rx_bytes <= rx_bytes_diff):
+            break
+        time.sleep(0.1)
+
+    if (tx_pkts != None):
+        test.assertGreaterEqual(tx_pkts_diff, tx_pkts,
+            "Port TX packet counter is not updated correctly (expected increase of %d, got increase of %d)" % (tx_pkts, tx_pkts_diff))
+    if (rx_pkts != None):
+        test.assertGreaterEqual(rx_pkts_diff, rx_pkts,
+            "Port RX packet counter is not updated correctly (expected increase of %d, got increase of %d)" % (rx_pkts, rx_pkts_diff))
+    if (tx_bytes != None):
+        test.assertGreaterEqual(tx_bytes_diff, tx_bytes,
+            "Port TX byte counter is not updated correctly (expected increase of %d, got increase of %d)" % (tx_bytes, tx_bytes_diff))
+    if (rx_bytes != None):
+        test.assertGreaterEqual(rx_bytes_diff, rx_bytes,
+            "Port RX byte counter is not updated correctly (expected increase of %d, got increase of %d)" % (rx_bytes, rx_bytes_diff))
+
+def verify_queue_stats(test, port_no, queue_id,
+                       initial=[],
+                       pkts=None, bytes=None):
+    """
+    Verify that queue stats changed as expected.
+
+    Optionally takes an 'initial' list of stats entries, as returned by
+    get_queue_stats(). If 'initial' is not given the counters are assumed to
+    begin at 0.
+    """
+    def accumulate(stats):
+        pkts_acc = bytes_acc = 0
+        for stat in stats:
+            pkts_acc += stat.tx_packets
+            bytes_acc += stat.tx_bytes
+        return (pkts_acc, bytes_acc)
+
+    pkts_before, bytes_before = accumulate(initial)
+
+    # Wait 10s for counters to update
+    pkt_diff = byte_diff = None
+    for i in range(0, 100):
+        stats = get_queue_stats(test, port_no, queue_id)
+        pkts_after, bytes_after = accumulate(stats)
+        pkt_diff = pkts_after - pkts_before
+        byte_diff = bytes_after - bytes_before
+        if (pkts == None or pkt_diff >= pkts) and \
+           (bytes == None or byte_diff >= bytes):
+            break
+        time.sleep(0.1)
+
+    if pkts != None:
+        test.assertEquals(pkt_diff, pkts, "Queue packet counter not updated properly (expected increase of %d, got increase of %d)" % (pkts, pkt_diff))
+
+    if bytes != None:
+        test.assertTrue(byte_diff >= bytes and byte_diff <= bytes*1.1,
+                        "Queue byte counter not updated properly (expected increase of %d, got increase of %d)" % (bytes, byte_diff))
+
+def packet_in_match(msg, data, in_port=None, reason=None):
+    """
+    Check whether the packet_in message 'msg' has fields matching 'data',
+    'in_port', and 'reason'.
+
+    This function handles truncated packet_in data. The 'in_port' and 'reason'
+    parameters are optional.
+
+    @param msg packet_in message
+    @param data Expected packet_in data
+    @param in_port Expected packet_in in_port, or None
+    @param reason Expected packet_in reason, or None
+    """
+
+    if ofp.OFP_VERSION <= 2:
+        pkt_in_port = msg.in_port
+    else:
+        oxms = { type(oxm): oxm for oxm in msg.match.oxm_list }
+        if ofp.oxm.in_port in oxms:
+            pkt_in_port = oxms[ofp.oxm.in_port].value
+        else:
+            logging.warn("Missing in_port in packet-in message")
+            pkt_in_port = None
+
+    if in_port != None and in_port != pkt_in_port:
+        logging.debug("Incorrect packet_in in_port (expected %d, received %d)", in_port, pkt_in_port)
+        return False
+
+    if reason != None and reason != msg.reason:
+        logging.debug("Incorrect packet_in reason (expected %d, received %d)", reason, msg.reason)
+        return False
+
+    # Check that one of the packets is a prefix of the other.
+    # The received packet may be either truncated or padded, but not both.
+    # (Some of the padding may be truncated but that's irrelevant). We
+    # need to check that the smaller packet is a prefix of the larger one.
+    # Note that this check succeeds if the switch sends a zero-length
+    # packet-in.
+    compare_len = min(len(msg.data), len(data))
+    if data[:compare_len] != msg.data[:compare_len]:
+        logging.debug("Incorrect packet_in data")
+        logging.debug("Expected %s" % format_packet(data[:compare_len]))
+        logging.debug("Received %s" % format_packet(msg.data[:compare_len]))
+        return False
+
+    return True
+
+def verify_packet_in(test, data, in_port, reason, controller=None):
+    """
+    Assert that the controller receives a packet_in message matching data 'data'
+    from port 'in_port' with reason 'reason'. Does not trigger the packet_in
+    itself, that's up to the test case.
+
+    @param test Instance of base_tests.SimpleProtocol
+    @param pkt String to expect as the packet_in data
+    @param in_port OpenFlow port number to expect as the packet_in in_port
+    @param reason One of OFPR_* to expect as the packet_in reason
+    @param controller Controller instance, defaults to test.controller
+    @returns The received packet-in message
+    """
+
+    if controller == None:
+        controller = test.controller
+
+    end_time = time.time() + oftest.ofutils.default_timeout
+
+    while True:
+        msg, _ = controller.poll(ofp.OFPT_PACKET_IN, end_time - time.time())
+        if not msg:
+            # Timeout
+            break
+        elif packet_in_match(msg, data, in_port, reason):
+            # Found a matching message
+            break
+
+    test.assertTrue(msg is not None, 'Packet in message not received on port %r' % in_port)
+    return msg
+
+def verify_no_packet_in(test, data, in_port, controller=None):
+    """
+    Assert that the controller does not receive a packet_in message matching
+    data 'data' from port 'in_port'.
+
+    @param test Instance of base_tests.SimpleProtocol
+    @param pkt String to expect as the packet_in data
+    @param in_port OpenFlow port number to expect as the packet_in in_port
+    @param controller Controller instance, defaults to test.controller
+    """
+
+    if controller == None:
+        controller = test.controller
+
+    # Negative test, need to wait a short amount of time before checking we
+    # didn't receive the message.
+    time.sleep(oftest.ofutils.default_negative_timeout)
+
+    # Check every packet_in queued in the controller
+    while True:
+        msg, _ = controller.poll(ofp.OFPT_PACKET_IN, timeout=0)
+        if msg == None:
+            # No more queued packet_in messages
+            break
+        elif packet_in_match(msg, data, in_port, None):
+            # Found a matching message
+            break
+
+    if in_port == None:
+        test.assertTrue(msg == None, "Did not expect a packet-in message on any port")
+    else:
+        test.assertTrue(msg == None, "Did not expect a packet-in message on port %d" % in_port)
+
+def openflow_ports(num=None):
+    """
+    Return a list of 'num' OpenFlow port numbers
+
+    If 'num' is None, return all available ports. Otherwise, limit the length
+    of the result to 'num' and raise an exception if not enough ports are
+    available.
+    """
+    ports = sorted(oftest.config["port_map"].keys())
+    if num != None and len(ports) < num:
+        raise Exception("test requires %d ports but only %d are available" % (num, len(ports)))
+    return ports[:num]
+
+def verify_packet(test, pkt, ofport):
+    """
+    Check that an expected packet is received
+    """
+    logging.debug("Checking for pkt on port %r", ofport)
+    (rcv_port, rcv_pkt, pkt_time) = test.dataplane.poll(port_number=ofport, exp_pkt=str(pkt))
+    test.assertTrue(rcv_pkt != None, "Did not receive pkt on %r" % ofport)
+    return (rcv_port, rcv_pkt, pkt_time)
+
+def verify_no_packet(test, pkt, ofport):
+    """
+    Check that a particular packet is not received
+    """
+    logging.debug("Negative check for pkt on port %r", ofport)
+    (rcv_port, rcv_pkt, pkt_time) = \
+        test.dataplane.poll(
+            port_number=ofport, exp_pkt=str(pkt),
+            timeout=oftest.ofutils.default_negative_timeout)
+    test.assertTrue(rcv_pkt == None, "Received packet on %r" % ofport)
+
+def verify_no_other_packets(test):
+    """
+    Check that no unexpected packets are received
+
+    This is a no-op if the --relax option is in effect.
+    """
+    if oftest.config["relax"]:
+        return
+    logging.debug("Checking for unexpected packets on all ports")
+    (rcv_port, rcv_pkt, pkt_time) = test.dataplane.poll(timeout=oftest.ofutils.default_negative_timeout)
+    if rcv_pkt != None:
+        logging.debug("Received unexpected packet on port %r: %s", rcv_port, format_packet(rcv_pkt))
+    test.assertTrue(rcv_pkt == None, "Unexpected packet on port %r" % rcv_port)
+
+def verify_packets(test, pkt, ofports):
+    """
+    Check that a packet is received on certain ports
+
+    Also verifies that the packet is not received on any other ports, and that no
+    other packets are received (unless --relax is in effect).
+
+    This covers the common and simplest cases for checking dataplane outputs.
+    For more complex usage, like multiple different packets being output, or
+    multiple packets on the same port, use the primitive verify_packet,
+    verify_no_packet, and verify_no_other_packets functions directly.
+    """
+    pkt = str(pkt)
+    for ofport in openflow_ports():
+        if ofport in ofports:
+            verify_packet(test, pkt, ofport)
+        else:
+            verify_no_packet(test, pkt, ofport)
+    verify_no_other_packets(test)
+
+def verify_no_errors(ctrl):
+    error, _ = ctrl.poll(ofp.OFPT_ERROR, 0)
+    if error:
+        raise AssertionError("unexpected error type=%d code=%d" % (error.err_type, error.code))
+
+def verify_capability(test, capability):
+    """
+    Return True if DUT supports the specified capability.
+
+    @param test Instance of base_tests.SimpleProtocol
+    @param capability One of ofp_capabilities.
+    """
+    logging.info("Verifing that capability code is valid.")
+    test.assertIn(capability, ofp.const.ofp_capabilities_map,
+                  "Capability code %d does not exist." % capability)
+    capability_str = ofp.const.ofp_capabilities_map[capability]
+
+    logging.info(("Sending features_request to test if capability "
+                  "%s is supported."), capability_str)
+    req = ofp.message.features_request()
+    res, raw = test.controller.transact(req)
+    test.assertIsNotNone(res, "Did not receive a response from the DUT.")
+    test.assertEqual(res.type, ofp.OFPT_FEATURES_REPLY,
+                     ("Unexpected packet type %d received in response to "
+                      "OFPT_FEATURES_REQUEST") % res.type)
+    logging.info("Received features_reply.")
+
+    if (res.capabilities & capability) > 0:
+        logging.info("Switch capabilities bitmask claims to support %s",
+                     capability_str)
+        return True, res.capabilities
+    else:
+        logging.info("Capabilities bitmask does not support %s.",
+                     capability_str)
+        return False, res.capabilities
+
+def verify_configuration_flag(test, flag):
+    """
+    Return True if DUT supports specified configuration flag.
+
+    @param test Instance of base_tests.SimpleProtocol
+    @param flag One of ofp_config_flags.
+    @returns (supported, flags) Bool if flag is set and flag values.
+    """
+    logging.info("Verifing that flag is valid.")
+    test.assertIn(flag, ofp.const.ofp_config_flags_map,
+                  "flag  %s does not exist." % flag)
+    flag_str = ofp.const.ofp_config_flags_map[flag]
+
+    logging.info("Sending OFPT_GET_CONFIG_REQUEST.")
+    req = ofp.message.get_config_request()
+    rv = test.controller.message_send(req)
+    test.assertNotEqual(rv, -1, "Not able to send get_config_request.")
+
+    logging.info("Expecting OFPT_GET_CONFIG_REPLY ")
+    (res, pkt) = test.controller.poll(exp_msg=ofp.OFPT_GET_CONFIG_REPLY,
+                                      timeout=2)
+    test.assertIsNotNone(res, "Did not receive OFPT_GET_CONFIG_REPLY")
+    logging.info("Received OFPT_GET_CONFIG_REPLY ")
+
+    if res.flags == flag:
+        logging.info("%s flag is set.", flag_str)
+        return True, res.flags
+    else:
+        logging.info("%s flag is not set.", flag_str)
+        return False, res.flags
+
+__all__ = list(set(locals()) - _import_blacklist)
diff --git a/Fabric/Utilities/src/python/oftest/utils.py b/Fabric/Utilities/src/python/oftest/utils.py
new file mode 100644
index 0000000..ebc168d
--- /dev/null
+++ b/Fabric/Utilities/src/python/oftest/utils.py
@@ -0,0 +1,779 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+import Queue
+import itertools
+
+from oftest.testutils import *
+from accton_util import *
+
+"""
+MISC
+"""
+
+def print_port_stats(test, port):
+    entries = get_port_stats(test, port)
+    for item in entries:
+        packet_rcv          = item.rx_packets
+        packet_rcv_dropped  = item.rx_dropped
+        packet_rcv_errors   = item.rx_errors
+
+        packet_sent         = item.tx_packets
+        packet_sent_dropped = item.tx_dropped
+        packet_sent_errors  = item.tx_errors
+
+    print "\nPort %d stats count: tx %d rx %d - tx_dropped %d rx_dropped %d - tx_errors %d rx_errors %d" % (
+        port, packet_sent, packet_rcv, packet_sent_dropped, packet_rcv_dropped, packet_sent_errors, packet_rcv_errors
+        )
+
+def filter_dhcp(controller):
+    match = ofp.match( )
+    match.oxm_list.append( ofp.oxm.eth_type( 0x0800 ) )
+    match.oxm_list.append( ofp.oxm.ip_proto( 17 ) )
+    match.oxm_list.append( ofp.oxm.udp_src( 68 ) )
+    match.oxm_list.append( ofp.oxm.udp_dst( 67 ))
+    request = ofp.message.flow_add(
+        table_id=60,
+        cookie=42,
+        match=match,
+        instructions=[ofp.instruction.clear_actions( )],
+        buffer_id=ofp.OFP_NO_BUFFER,
+        priority=1
+        )
+    controller.message_send( request )
+    do_barrier( controller )
+
+def filter_ipv6(controller):
+    match = ofp.match( )
+    match.oxm_list.append( ofp.oxm.eth_type( 0x86dd ) )
+    request = ofp.message.flow_add(
+        table_id=60,
+        cookie=42,
+        match=match,
+        instructions=[ofp.instruction.clear_actions( )],
+        buffer_id=ofp.OFP_NO_BUFFER,
+        priority=1
+        )
+    controller.message_send( request )
+    do_barrier( controller )
+
+def filter_igmp(controller):
+    match = ofp.match( )
+    match.oxm_list.append( ofp.oxm.eth_type( 0x0800 ) )
+    match.oxm_list.append( ofp.oxm.ip_proto( 2 ) )
+    request = ofp.message.flow_add(
+        table_id=60,
+        cookie=42,
+        match=match,
+        instructions=[ofp.instruction.clear_actions( )],
+        buffer_id=ofp.OFP_NO_BUFFER,
+        priority=1
+        )
+    controller.message_send( request )
+    do_barrier( controller )
+
+"""
+MULTICAST Pipelines
+"""
+
+def fill_mcast_pipeline_L3toL2(
+    controller,
+    logging,
+    ports,
+    is_ingress_tagged,
+    is_egress_tagged,
+    is_vlan_translated,
+    is_max_vlan
+    ):
+    """
+    This method, according to the scenario, fills properly
+    the pipeline. The method generates using ports data the
+    necessary information to fill the multicast pipeline and
+    fills properly the pipeline which consists in this scenario:
+
+    i) to create l2 interface groups;
+    ii) to create l3 multicast groups;
+    iii) to add multicast flows;
+    iv) to add termination; flows;
+    v) to add vlan flows
+
+    Scenarios:
+    1) ingress untagged, egress untagged
+    2) ingress untagged, egress tagged
+    3) ingress tagged, egress untagged
+    4) ingress tagged, egress tagged, no translation
+    5) ingress tagged, egress tagged, translation
+    """
+
+    MAX_INTERNAL_VLAN           = 4094
+    # Used for no translation
+    FIXED_VLAN                  = 300
+    Groups                      = Queue.LifoQueue( )
+    L2_Groups                   = []
+    port_to_in_vlan             = {}
+    port_to_out_vlan            = {}
+    port_to_src_mac             = {}
+    port_to_src_mac_str         = {}
+    port_to_dst_mac             = {}
+    port_to_dst_mac_str         = {}
+    port_to_src_ip              = {}
+    port_to_src_ip_str          = {}
+    src_ip_0                    = 0xc0a80100
+    src_ip_0_str                = "192.168.1.%s"
+    dst_ip                      = 0xe0000001
+    switch_mac                  = [ 0x01, 0x00, 0x5e, 0x00, 0x00, 0x00 ]
+
+    for port in ports:
+        in_vlan_id  = port + 1
+        out_vlan_id = MAX_INTERNAL_VLAN - port
+        if is_max_vlan and not is_vlan_translated:
+            in_vlan_id  = MAX_INTERNAL_VLAN
+            out_vlan_id = MAX_INTERNAL_VLAN
+        elif not is_max_vlan and not is_vlan_translated:
+            in_vlan_id  = FIXED_VLAN
+            out_vlan_id = FIXED_VLAN
+        src_mac                     = [ 0x00, 0x11, 0x11, 0x11, 0x11, port ]
+        src_mac_str                 = ':'.join( [ '%02X' % x for x in src_mac ] )
+        dst_mac                     = [ 0x01, 0x00, 0x5e, 0x01, 0x01, port ]
+        dst_mac_str                 = ':'.join( [ '%02X' % x for x in dst_mac ] )
+        src_ip                      = src_ip_0 + port
+        src_ip_str                  = src_ip_0_str % port
+        port_to_in_vlan[port]       = in_vlan_id
+        port_to_out_vlan[port]      = out_vlan_id
+        port_to_src_mac[port]       = src_mac
+        port_to_src_mac_str[port]   = src_mac_str
+        port_to_dst_mac[port]       = dst_mac
+        port_to_dst_mac_str[port]   = dst_mac_str
+        port_to_src_ip[port]        = src_ip
+        port_to_src_ip_str[port]    = src_ip_str
+
+    for in_port in ports:
+
+        L2_Groups = []
+        # add vlan flows table
+        add_one_vlan_table_flow( controller, in_port, 1, port_to_in_vlan[in_port], flag=VLAN_TABLE_FLAG_ONLY_TAG )
+        if not is_ingress_tagged:
+            add_one_vlan_table_flow( controller, in_port, 1, port_to_in_vlan[in_port], flag=VLAN_TABLE_FLAG_ONLY_UNTAG )
+        elif is_vlan_translated:
+            add_one_vlan_table_flow_translation( controller, in_port, port_to_in_vlan[in_port], port_to_out_vlan[in_port], flag=VLAN_TABLE_FLAG_ONLY_TAG)
+        # add termination flow
+        if not is_vlan_translated:
+            add_termination_flow( controller, in_port, 0x0800, switch_mac, port_to_in_vlan[in_port] )
+        else:
+            add_termination_flow( controller, in_port, 0x0800, switch_mac, port_to_out_vlan[in_port] )
+
+        for out_port in ports:
+            if out_port == in_port:
+                continue
+            # add l2 interface group, vlan_id equals for each port and must coincide with mcast_group vlan_id
+            if not is_vlan_translated:
+                l2gid, msg = add_one_l2_interface_group( controller, out_port, vlan_id=port_to_in_vlan[in_port],
+                is_tagged=is_egress_tagged, send_barrier=True )
+            else:
+                l2gid, msg = add_one_l2_interface_group( controller, out_port, vlan_id=port_to_out_vlan[in_port],
+                is_tagged=is_egress_tagged, send_barrier=True )
+            Groups._put( l2gid )
+            L2_Groups.append( l2gid )
+
+        # add l3 mcast group
+        if not is_vlan_translated:
+            mcat_group_msg = add_l3_mcast_group( controller, port_to_in_vlan[in_port], in_port, L2_Groups )
+        else:
+            mcat_group_msg = add_l3_mcast_group( controller, port_to_out_vlan[in_port], in_port, L2_Groups )
+        Groups._put( mcat_group_msg.group_id )
+        # add mcast routing flow
+        if not is_vlan_translated:
+            add_mcast4_routing_flow( controller, port_to_in_vlan[in_port], port_to_src_ip[in_port], 0, dst_ip, mcat_group_msg.group_id )
+        else:
+            add_mcast4_routing_flow( controller, port_to_out_vlan[in_port], port_to_src_ip[in_port], 0, dst_ip, mcat_group_msg.group_id )
+
+    return (
+        port_to_in_vlan,
+        port_to_out_vlan,
+        port_to_src_mac_str,
+        port_to_dst_mac_str,
+        port_to_src_ip,
+        port_to_src_ip_str,
+        Groups
+        )
+
+def fill_mcast_pipeline_L3toL3(
+    controller,
+    logging,
+    ports,
+    is_ingress_tagged,
+    is_egress_tagged,
+    is_vlan_translated,
+    is_max_vlan
+    ):
+    """
+    This method, according to the scenario, fills properly
+    the pipeline. The method generates using ports data the
+    necessary information to fill the multicast pipeline and
+    fills properly the pipeline which consists in this scenario:
+
+    i) to create l2 interface groups;
+    ii)to create l3 interface groups;
+    iii) to create l3 multicast groups;
+    iv) to add multicast flows;
+    v) to add termination; flows;
+    vi) to add vlan flows
+
+    Scenarios:
+    1) ingress tagged, egress tagged, translation
+    """
+
+    Groups                      = Queue.LifoQueue( )
+    MAX_INTERNAL_VLAN           = 4094
+    port_to_in_vlan             = {}
+    port_to_out_vlan            = {}
+    port_to_src_mac             = {}
+    port_to_src_mac_str         = {}
+    port_to_dst_mac             = {}
+    port_to_dst_mac_str         = {}
+    port_to_src_ip              = {}
+    port_to_src_ip_str          = {}
+    port_to_intf_src_mac        = {}
+    port_to_intf_src_mac_str    = {}
+    src_ip_0                    = 0xc0a80100
+    src_ip_0_str                = "192.168.1.%s"
+    dst_ip                      = 0xe0000001
+    switch_mac                  = [ 0x01, 0x00, 0x5e, 0x00, 0x00, 0x00 ]
+
+    for port in ports:
+        in_vlan_id                     = port + 1
+        out_vlan_id                    = MAX_INTERNAL_VLAN - port
+        src_mac                        = [ 0x00, 0x11, 0x11, 0x11, 0x11, port ]
+        src_mac_str                    = ':'.join( [ '%02X' % x for x in src_mac ] )
+        dst_mac                        = [ 0x01, 0x00, 0x5e, 0x01, 0x01, port ]
+        dst_mac_str                    = ':'.join( [ '%02X' % x for x in dst_mac ] )
+        src_ip                         = src_ip_0 + port
+        src_ip_str                     = src_ip_0_str % port
+        intf_src_mac                   = [ 0x00, 0x00, 0x00, 0xcc, 0xcc, port ]
+        intf_src_mac_str               = ':'.join( [ '%02X' % x for x in intf_src_mac ] )
+        port_to_in_vlan[port]          = in_vlan_id
+        port_to_out_vlan[port]         = out_vlan_id
+        port_to_src_mac[port]          = src_mac
+        port_to_src_mac_str[port]      = src_mac_str
+        port_to_dst_mac[port]          = dst_mac
+        port_to_dst_mac_str[port]      = dst_mac_str
+        port_to_src_ip[port]           = src_ip
+        port_to_src_ip_str[port]       = src_ip_str
+        port_to_intf_src_mac[port]     = intf_src_mac
+        port_to_intf_src_mac_str[port] = intf_src_mac_str
+
+    for port in ports:
+        L3_Groups = []
+        for other_port in ports:
+            # add l2 interface group
+            l2gid, msg = add_one_l2_interface_group( controller, other_port, vlan_id=port_to_out_vlan[other_port],
+            is_tagged=True, send_barrier=True )
+            Groups._put( l2gid )
+            # add l3 interface group
+            l3group_ucast_msg = add_l3_interface_group( controller, other_port, port_to_out_vlan[other_port], port_to_in_vlan[other_port],
+            port_to_intf_src_mac[other_port] )
+            L3_Groups.append(l3group_ucast_msg.group_id)
+            Groups._put( l3group_ucast_msg.group_id )
+
+        # add mcast group
+        mcat_group_msg = add_l3_mcast_group( controller, port_to_in_vlan[port], port_to_in_vlan[port], L3_Groups )
+        do_barrier(controller)
+        Groups._put( mcat_group_msg.group_id )
+        # add mcast flow
+        add_mcast4_routing_flow( controller, port_to_in_vlan[port], port_to_src_ip[port], 0, dst_ip, mcat_group_msg.group_id, True )
+        # add termination flow
+        add_termination_flow( controller, port, 0x0800, switch_mac, port_to_in_vlan[port] )
+        # add vlan flow table
+        add_one_vlan_table_flow( controller, port, 1, port_to_in_vlan[port], flag=VLAN_TABLE_FLAG_ONLY_TAG )
+
+    return (
+        port_to_in_vlan,
+        port_to_out_vlan,
+        port_to_src_mac_str,
+        port_to_dst_mac_str,
+        port_to_src_ip,
+        port_to_src_ip_str,
+        port_to_intf_src_mac_str,
+        Groups
+        )
+
+"""
+VPWS Pipeline
+"""
+
+OF_DPA_MPLS_L2_VPN_Label     = 1
+OF_DPA_MPLS_Tunnel_Label_1   = 3
+OF_DPA_MPLS_Tunnel_Label_2   = 4
+
+EGRESS_UNTAGGED     = 1
+EGRESS_TAGGED       = 2
+EGRESS_TAGGED_TRANS = 3
+
+
+def fill_pw_initiation_pipeline(
+    controller,
+    logging,
+    in_port,
+    out_port,
+    ingress_tags,
+    egress_tag,
+    mpls_labels
+    ):
+    """
+    This method, according to the scenario, fills properly
+    the pw pipeline. The method generates using ports data the
+    necessary information to fill the pw pipeline and
+    fills properly the pipeline which consists into:
+
+    """
+
+    Groups                  = Queue.LifoQueue( )
+    out_vlan                = 4094
+    port_to_in_vlan_1       = {}
+    port_to_in_vlan_2       = {}
+    port_to_in_vlan_3       = {}
+    port_to_src_mac         = {}
+    port_to_src_mac_str     = {}
+    port_to_dst_mac         = {}
+    port_to_dst_mac_str     = {}
+    port_to_mpls_label_1    = {}
+    port_to_mpls_label_2    = {}
+    port_to_mpls_label_pw   = {}
+    ports                   = [in_port, out_port]
+
+    for port in ports:
+        in_vlan_id_1                = port + 1
+        in_vlan_id_2                = port + 100
+        in_vlan_id_3                = port + 300
+        mpls_label_1                = port + 100
+        mpls_label_2                = port + 200
+        mpls_label_pw               = port + 300
+        port_to_in_vlan_1[port]     = in_vlan_id_1
+        port_to_in_vlan_2[port]     = in_vlan_id_2
+        port_to_in_vlan_3[port]     = in_vlan_id_3
+        src_mac                     = [ 0x00, 0x00, 0x00, 0x00, 0x11, port ]
+        src_mac_str                 = ':'.join( [ '%02X' % x for x in src_mac ] )
+        dst_mac                     = [ 0x00, 0x00, 0x00, 0x11, 0x11, port ]
+        dst_mac_str                 = ':'.join( [ '%02X' % x for x in dst_mac ] )
+        port_to_src_mac[port]       = src_mac
+        port_to_src_mac_str[port]   = src_mac_str
+        port_to_dst_mac[port]       = dst_mac
+        port_to_dst_mac_str[port]   = dst_mac_str
+        port_to_mpls_label_1[port]  = mpls_label_1
+        port_to_mpls_label_2[port]  = mpls_label_2
+        port_to_mpls_label_pw[port] = mpls_label_pw
+
+    # add l2 interface group, we have to pop the VLAN;
+    l2_intf_gid, l2_intf_msg = add_one_l2_interface_group(
+        ctrl=controller,
+        port=out_port,
+        vlan_id=out_vlan,
+        is_tagged=False,
+        send_barrier=False
+        )
+    Groups._put( l2_intf_gid )
+    # add MPLS interface group
+    mpls_intf_gid, mpls_intf_msg = add_mpls_intf_group(
+        ctrl=controller,
+        ref_gid=l2_intf_gid,
+        dst_mac=port_to_dst_mac[in_port],
+        src_mac=port_to_src_mac[out_port],
+        vid=out_vlan,
+        index=in_port
+        )
+    Groups._put( mpls_intf_gid )
+    mpls_gid = mpls_intf_gid
+    # add MPLS tunnel label groups, the number depends on the labels
+    if mpls_labels == 2:
+        mpls_tunnel_gid, mpls_tunnel_msg = add_mpls_tunnel_label_group(
+        ctrl=controller,
+        ref_gid=mpls_intf_gid,
+        subtype=OF_DPA_MPLS_Tunnel_Label_2,
+        index=in_port,
+        label=port_to_mpls_label_2[in_port]
+        )
+        Groups._put( mpls_tunnel_gid )
+        mpls_tunnel_gid, mpls_tunnel_msg = add_mpls_tunnel_label_group(
+            ctrl=controller,
+            ref_gid=mpls_tunnel_gid,
+            subtype=OF_DPA_MPLS_Tunnel_Label_1,
+            index=in_port,
+            label=port_to_mpls_label_1[in_port]
+            )
+        Groups._put( mpls_tunnel_gid )
+        mpls_gid = mpls_tunnel_gid
+    elif mpls_labels == 1:
+        mpls_tunnel_gid, mpls_tunnel_msg = add_mpls_tunnel_label_group(
+            ctrl=controller,
+            ref_gid=mpls_intf_gid,
+            subtype=OF_DPA_MPLS_Tunnel_Label_1,
+            index=in_port,
+            label=port_to_mpls_label_1[in_port]
+            )
+        Groups._put( mpls_tunnel_gid )
+        mpls_gid = mpls_tunnel_gid
+    # add MPLS L2 VPN group
+    mpls_l2_vpn_gid, mpls_l2_vpn_msg = add_mpls_label_group(
+        ctrl=controller,
+        subtype=OF_DPA_MPLS_L2_VPN_Label,
+        index=in_port,
+        ref_gid=mpls_gid,
+        push_l2_header=True,
+        push_vlan=True,
+        push_mpls_header=True,
+        push_cw=True,
+        set_mpls_label=port_to_mpls_label_pw[in_port],
+        set_bos=1,
+        cpy_ttl_outward=True
+    )
+    Groups._put( mpls_l2_vpn_gid )
+    # add MPLS L2 port flow
+    add_mpls_l2_port_flow(
+        ctrl=controller,
+        of_port=in_port,
+        mpls_l2_port=in_port,
+        tunnel_index=1,
+        ref_gid=mpls_l2_vpn_gid
+        )
+    # add VLAN flows table
+    if ingress_tags == 2:
+        if egress_tag == EGRESS_TAGGED:
+            add_one_vlan_1_table_flow_pw(
+                ctrl=controller,
+                of_port=in_port,
+                tunnel_index=1,
+                new_outer_vlan_id=-1,
+                outer_vlan_id=port_to_in_vlan_2[in_port],
+                inner_vlan_id=port_to_in_vlan_1[in_port],
+                )
+        elif egress_tag == EGRESS_TAGGED_TRANS:
+            add_one_vlan_1_table_flow_pw(
+                ctrl=controller,
+                of_port=in_port,
+                tunnel_index=1,
+                new_outer_vlan_id=port_to_in_vlan_3[in_port],
+                outer_vlan_id=port_to_in_vlan_2[in_port],
+                inner_vlan_id=port_to_in_vlan_1[in_port],
+                )
+        add_one_vlan_table_flow(
+            ctrl=controller,
+            of_port=in_port,
+            vlan_id=port_to_in_vlan_2[in_port],
+            flag=VLAN_TABLE_FLAG_ONLY_STACKED,
+            )
+    elif ingress_tags == 1:
+        if egress_tag == EGRESS_TAGGED:
+            add_one_vlan_table_flow_pw(
+                ctrl=controller,
+                of_port=in_port,
+                tunnel_index=1,
+                vlan_id=port_to_in_vlan_1[in_port],
+                flag=VLAN_TABLE_FLAG_ONLY_TAG,
+                )
+        elif egress_tag == EGRESS_TAGGED_TRANS:
+            add_one_vlan_table_flow_pw(
+                ctrl=controller,
+                of_port=in_port,
+                tunnel_index=1,
+                vlan_id=port_to_in_vlan_1[in_port],
+                new_vlan_id=port_to_in_vlan_3[in_port],
+                flag=VLAN_TABLE_FLAG_ONLY_TAG,
+                )
+    elif ingress_tags == 0:
+        filter_dhcp(controller)
+        filter_ipv6(controller)
+        filter_igmp(controller)
+        if egress_tag == EGRESS_UNTAGGED:
+            add_one_vlan_table_flow_pw(
+                ctrl=controller,
+                of_port=in_port,
+                tunnel_index=1,
+                flag=VLAN_TABLE_FLAG_ONLY_UNTAG,
+                )
+        elif egress_tag == EGRESS_TAGGED:
+            add_one_vlan_table_flow_pw(
+                ctrl=controller,
+                of_port=in_port,
+                tunnel_index=1,
+                vlan_id=port_to_in_vlan_1[in_port],
+                flag=VLAN_TABLE_FLAG_ONLY_UNTAG,
+                )
+
+    return (
+        port_to_mpls_label_2,
+        port_to_mpls_label_1,
+        port_to_mpls_label_pw,
+        port_to_in_vlan_3,
+        port_to_in_vlan_2,
+        port_to_in_vlan_1,
+        port_to_src_mac_str,
+        port_to_dst_mac_str,
+        Groups
+        )
+
+MPLS_FLOW_TABLE_0           = 23
+OF_DPA_MPLS_SWAP_Label      = 5
+
+def fill_pw_intermediate_transport_pipeline(
+    controller,
+    logging,
+    ports,
+    mpls_labels
+    ):
+    """
+    This method, according to the scenario, fills properly
+    the pw pipeline. The method generates using ports data the
+    necessary information to fill the pw pipeline and
+    fills properly the pipeline which consists into:
+
+    """
+
+    Groups                  = Queue.LifoQueue( )
+    out_vlan                = 4094
+    port_to_src_mac         = {}
+    port_to_src_mac_str     = {}
+    port_to_dst_mac         = {}
+    port_to_dst_mac_str     = {}
+    port_to_mpls_label_2    = {}
+    port_to_mpls_label_1    = {}
+    port_to_mpls_label_pw   = {}
+    port_to_switch_mac      = {}
+    port_to_switch_mac_str  = {}
+
+    for port in ports:
+        mpls_label_1                    = port + 10
+        mpls_label_2                    = port + 100
+        mpls_label_pw                   = port + 300
+        src_mac                         = [ 0x00, 0x00, 0x00, 0x00, 0x11, port ]
+        src_mac_str                     = ':'.join( [ '%02X' % x for x in src_mac ] )
+        dst_mac                         = [ 0x00, 0x00, 0x00, 0x11, 0x11, port ]
+        dst_mac_str                     = ':'.join( [ '%02X' % x for x in dst_mac ] )
+        switch_mac                      = [ 0x00, 0x00, 0x00, 0x00, 0x00, port ]
+        switch_mac_str                  = ':'.join( [ '%02X' % x for x in switch_mac ] )
+        port_to_src_mac[port]           = src_mac
+        port_to_src_mac_str[port]       = src_mac_str
+        port_to_dst_mac[port]           = dst_mac
+        port_to_dst_mac_str[port]       = dst_mac_str
+        port_to_mpls_label_1[port]      = mpls_label_1
+        port_to_mpls_label_2[port]      = mpls_label_2
+        port_to_mpls_label_pw[port]     = mpls_label_pw
+        port_to_switch_mac[port]        = switch_mac
+        port_to_switch_mac_str[port]    = switch_mac_str
+
+    for pair in itertools.product(ports, ports):
+        in_port     = pair[0]
+        out_port    = pair[1]
+        if out_port == in_port:
+            continue
+        # add l2 interface group, we have to pop the VLAN;
+        l2_intf_gid, l2_intf_msg = add_one_l2_interface_group(
+            ctrl=controller,
+            port=out_port,
+            vlan_id=out_vlan,
+            is_tagged=False,
+            send_barrier=False
+            )
+        Groups._put( l2_intf_gid )
+        # add MPLS interface group
+        mpls_intf_gid, mpls_intf_msg = add_mpls_intf_group(
+            ctrl=controller,
+            ref_gid=l2_intf_gid,
+            dst_mac=port_to_dst_mac[in_port],
+            src_mac=port_to_src_mac[out_port],
+            vid=out_vlan,
+            index=in_port
+            )
+        Groups._put( mpls_intf_gid )
+        # add MPLS flows
+        if mpls_labels >=2:
+            add_mpls_flow_pw(
+                ctrl=controller,
+                action_group_id=mpls_intf_gid,
+                label=port_to_mpls_label_2[in_port],
+                ethertype=0x8847,
+                tunnel_index=1,
+                bos=0
+                )
+        else:
+            mpls_tunnel_gid, mpls_tunnel_msg = add_mpls_tunnel_label_group(
+                ctrl=controller,
+                ref_gid=mpls_intf_gid,
+                subtype=OF_DPA_MPLS_Tunnel_Label_2,
+                index=in_port,
+                label=port_to_mpls_label_2[in_port]
+                )
+            Groups._put( mpls_tunnel_gid )
+            mpls_tunnel_gid, mpls_tunnel_msg = add_mpls_tunnel_label_group(
+                ctrl=controller,
+                ref_gid=mpls_tunnel_gid,
+                subtype=OF_DPA_MPLS_Tunnel_Label_1,
+                index=in_port,
+                label=port_to_mpls_label_1[in_port]
+                )
+            Groups._put( mpls_tunnel_gid )
+            mpls_swap_gid, mpls_tunnel_msg = add_mpls_swap_label_group(
+                ctrl=controller,
+                ref_gid=mpls_tunnel_gid,
+                subtype=OF_DPA_MPLS_SWAP_Label,
+                index=in_port,
+                label=port_to_mpls_label_pw[in_port]
+                )
+            Groups._put( mpls_swap_gid )
+            add_mpls_flow_pw(
+                ctrl=controller,
+                action_group_id=mpls_swap_gid,
+                label=port_to_mpls_label_pw[in_port],
+                ethertype=0x8847,
+                tunnel_index=1,
+                bos=1,
+                popMPLS=False,
+                popL2=False
+                )
+        # add Termination flow
+        add_termination_flow(
+            ctrl=controller,
+            in_port=in_port,
+            eth_type=0x8847,
+            dst_mac=port_to_switch_mac[in_port],
+            vlanid=out_vlan,
+            goto_table=MPLS_FLOW_TABLE_0)
+        # add VLAN flows
+        add_one_vlan_table_flow(
+            ctrl=controller,
+            of_port=in_port,
+            vlan_id=out_vlan,
+            flag=VLAN_TABLE_FLAG_ONLY_TAG,
+            )
+        add_one_vlan_table_flow(
+            ctrl=controller,
+            of_port=in_port,
+            vlan_id=out_vlan,
+            flag=VLAN_TABLE_FLAG_ONLY_UNTAG
+            )
+
+    return (
+        port_to_mpls_label_2,
+        port_to_mpls_label_1,
+        port_to_mpls_label_pw,
+        port_to_switch_mac_str,
+        port_to_src_mac_str,
+        port_to_dst_mac_str,
+        Groups
+        )
+
+def fill_pw_termination_pipeline(
+    controller,
+    logging,
+    in_port,
+    out_port,
+    egress_tags
+    ):
+    """
+    This method, according to the scenario, fills properly
+    the pw pipeline. The method generates using ports data the
+    necessary information to fill the pw pipeline and
+    fills properly the pipeline which consists into:
+
+    """
+
+    Groups                  = Queue.LifoQueue( )
+    out_vlan                = 4094
+    port_to_mpls_label_pw   = {}
+    port_to_vlan_2          = {}
+    port_to_vlan_1          = {}
+    port_to_switch_mac      = {}
+    port_to_switch_mac_str  = {}
+    ports                   = [in_port, out_port]
+
+    for port in ports:
+        mpls_label_pw                   = port + 300
+        in_vlan_id_1                    = port + 1
+        in_vlan_id_2                    = port + 100
+        switch_mac                      = [ 0x00, 0x00, 0x00, 0x00, 0x11, port ]
+        switch_mac_str                  = ':'.join( [ '%02X' % x for x in switch_mac ] )
+        port_to_mpls_label_pw[port]     = mpls_label_pw
+        port_to_vlan_2[port]            = in_vlan_id_2
+        port_to_vlan_1[port]            = in_vlan_id_1
+        port_to_switch_mac[port]        = switch_mac
+        port_to_switch_mac_str[port]    = switch_mac_str
+
+    # add l2 interface group;
+    if egress_tags == 2:
+        l2_intf_gid, l2_intf_msg = add_one_l2_interface_group(
+            ctrl=controller,
+            port=out_port,
+            vlan_id=port_to_vlan_2[out_port],
+            is_tagged=True,
+            send_barrier=False
+            )
+    elif egress_tags == 1:
+        l2_intf_gid, l2_intf_msg = add_one_l2_interface_group(
+            ctrl=controller,
+            port=out_port,
+            vlan_id=port_to_vlan_1[out_port],
+            is_tagged=True,
+            send_barrier=False
+            )
+    elif egress_tags == 0:
+        l2_intf_gid, l2_intf_msg = add_one_l2_interface_group(
+            ctrl=controller,
+            port=out_port,
+            vlan_id=port_to_vlan_1[out_port],
+            is_tagged=False,
+            send_barrier=False
+            )
+
+    Groups._put( l2_intf_gid )
+    add_mpls_flow_pw(
+        ctrl=controller,
+        action_group_id=l2_intf_gid,
+        label=port_to_mpls_label_pw[out_port],
+        ethertype=0x6558,
+        bos=1,
+        tunnel_index=1,
+        popMPLS=True,
+        popL2=True,
+        of_port=in_port
+        )
+    # add Termination flow
+    add_termination_flow(
+        ctrl=controller,
+        in_port=in_port,
+        eth_type=0x8847,
+        dst_mac=port_to_switch_mac[in_port],
+        vlanid=out_vlan,
+        goto_table=MPLS_FLOW_TABLE_0)
+    # add VLAN flows
+    add_one_vlan_table_flow(
+        ctrl=controller,
+        of_port=in_port,
+        vlan_id=out_vlan,
+        flag=VLAN_TABLE_FLAG_ONLY_TAG,
+        )
+    add_one_vlan_table_flow(
+        ctrl=controller,
+        of_port=in_port,
+        vlan_id=out_vlan,
+        flag=VLAN_TABLE_FLAG_ONLY_UNTAG
+        )
+
+    return (
+        port_to_mpls_label_pw,
+        port_to_vlan_2,
+        port_to_vlan_1,
+        port_to_switch_mac_str,
+        Groups
+        )
diff --git a/Fabric/Utilities/tools/ovs-ctl/README b/Fabric/Utilities/tools/ovs-ctl/README
new file mode 100644
index 0000000..b2378f7
--- /dev/null
+++ b/Fabric/Utilities/tools/ovs-ctl/README
@@ -0,0 +1,212 @@
+###############################################################################
+#
+# ovs-ctl.py
+#
+###############################################################################
+
+ovs-ctl manages the initialization and execution of OVS instances as targets
+for OFTest execution. 
+
+
+-------------------------------------------------------------------------------
+INSTALLATION
+-------------------------------------------------------------------------------
+
+ovs-ctl requires OVS be built and installed on your local machine. 
+If you are new to OVS, the preferred method is:
+
+1. Download openvswitch-X.Y.Z from http://openvswitch.org/releases
+2. Untar, configure, build, and install openvswitch into a useful location:
+
+   # All OVS installations will go in to /opt/ovs:
+   > mkdir -p /opt/ovs
+   
+   # All OVS Source distributions will live in /opt/ovs/src:
+   > mkdir -p /opt/ovs/src
+
+   # Download and untar source for openvswitch 1.4.0:
+   > curl http://openvswitch.org/releases/openvswitch-1.4.0.tar.gz | tar -xzC /opt/ovs/src
+
+   # build and install:
+   > cd /opt/ovs/openvswitch-1.4.0
+   > ./configure --prefix=/opt/ovs/1.4.0 --with-linux=/lib/modules/`uname -r`/build
+   > make
+   > sudo make install
+
+   # Copy the OVS kernel module out of the build tree into the install tree:
+   > sudo cp /opt/ovs/src/openvswitch-1.4.0/datapath/linux/openvswitch_mod.ko /opt/ovs/1.4.0/sbin
+
+
+3. READ the comments and instructions in ovs-ctl-default.example.conf
+
+4. Copy ovs-ctl-default.example.conf from the local directory to /opt/ovs:
+   
+   > sudo cp ovs-ctl-default.example.conf /opt/ovs/ovs-ctl-default.conf
+
+5. Modify /opt/ovs/ovs-ctl-default.conf to match your existing installation(s). 
+   If you followed the directions and used the paths suggested in Step 2, then the default 
+   configuration file should work without modification. 
+   Otherwise, edit to point to your installation directorie(s). 
+
+
+
+-------------------------------------------------------------------------------
+EXAMPLE USAGE
+-------------------------------------------------------------------------------
+
+You can initialize and run your default configuration (as specified in the config files) as follows:
+
+> ./ovs-ctl
+
+You can stop a running configuration as follows:
+
+> ./ovs-ctl --kill
+
+You can initialize and run any configuration (as specified in the config files) as follows:
+
+> ./ovs-ctl --config 1.3.0
+> ./ovs-ctl --config 1.4.0
+> ./ovs-ctl --config MySomeOtherConfiguration
+
+You can output logging and verbose information with the --log and --verbose options. 
+
+By default, OVS is initialized with 4 veth ports. You can change this with the --port-count option. 
+
+
+
+CONFIG FILES
+------------
+
+The configuration file options are just convenient methods of storing values for the command line
+arguments. Every command line argument can be specified as a key in your configuration file. 
+
+You do not need a configuration file at all -- you can specify all required paths and values
+from the command line -- but this is not recommended for regular usage. 
+
+The precedence for these settings is in the following order:
+
+1. Command Line option, if specified, THEN
+2. The [ConfigName] section of all config files, both default, user, or command-line specified, THEN
+3. The [Defaults] section of all config files
+
+
+Note that you may have a section defined in the ovs-ctl-default.conf file, AND in your ~/.ovs-ctl file. 
+The settings will be merged together, with the values in ~/.ovs-ctl taking precedence:
+
+So, for example, you can have the local installation information for 1.4.0 specified in /opt/ovs/ovs-ctl-default.conf as follows:
+
+    [1.4.0]
+    # ovs-1.4.0, configured and built into /opt/ovs/1.4.0
+    # Can be selected with 'ovs-ctl.py --config 1.4.0'
+    ovs_src_dir:/opt/ovs/src/openvswitch-1.4.0
+    ovs_base_dir:/opt/ovs/1.4.0
+    ovs_runtime_dir:/var/run/ovs/1.4.0
+
+This can be used by everyone. 
+
+You can also have user-specific settings in ~/.ovs-ctl for your own execution:
+
+    [1.4.0]
+    # Put logfiles for my personal runs in my ~/ovs-logfiles directory:
+    ovs_vswitchd_log=~/.ovs-logfiles/vswitchd.log
+
+
+
+-------------------------------------------------------------------------------
+OPTIONS AND HELP
+-------------------------------------------------------------------------------
+
+This documentation is minimal.
+
+Please see ./ovs-ctl --help for a full list of options:
+
+usage: ovs-ctl.py [-h] [-cf FILE [FILE ...]] [-c CONFIG] [-d FILE] [-nd]
+                  [--dump-config] [--ovs-vswitchd-schema OVS_VSWITCHD_SCHEMA]
+                  [--ovs-vswitchd-log OVS_VSWITCHD_LOG]
+                  [--ovs-vswitchd OVS_VSWITCHD] [--ovs-vsctl OVS_VSCTL]
+                  [--ovs-ofctl OVS_OFCTL] [--ovsdb-tool OVSDB_TOOL]
+                  [--ovsdb-server OVSDB_SERVER] [--ovs-kmod OVS_KMOD]
+                  [--ovs-src-dir OVS_SRC_DIR] [--ovs-log-dir OVS_LOG_DIR]
+                  [--ovs-version OVS_VERSION] [--ovs-base-dir OVS_BASE_DIR]
+                  [--ovs-runtime-dir OVS_RUNTIME_DIR]
+                  [--ovs-db-sock OVS_DB_SOCK] [--ovs-db-file OVS_DB_FILE]
+                  [--dry] [--log] [--verbose] [--kill] [--keep-veths]
+                  [--no-kmod] [--vlog] [-p PORT_COUNT] [--bridge BRIDGE]
+                  [--cip CIP] [--cport CPORT] [--max_backoff MAX_BACKOFF]
+                  [--keep-db]
+
+optional arguments:
+  -h, --help            show this help message and exit
+  -cf FILE [FILE ...], --config-file FILE [FILE ...]
+                        Load settings from the given config file
+  -c CONFIG, --config CONFIG
+                        Use the specified configuration section
+  -d FILE, --default-config-file FILE
+                        Location of the local default config file
+  -nd, --no-default     Do not load the default config file
+  --dump-config         Dump the loaded configuration settings
+  --ovs-vswitchd-schema OVS_VSWITCHD_SCHEMA
+                        Path to the vswitchd.ovsschema file
+  --ovs-vswitchd-log OVS_VSWITCHD_LOG
+                        Path to the vswitchd log file
+  --ovs-vswitchd OVS_VSWITCHD
+                        Path to the target ovs-vswitchd binary
+  --ovs-vsctl OVS_VSCTL
+                        Path to the target ovs-vsctl binary
+  --ovs-ofctl OVS_OFCTL
+                        Path to the target ovs-ofctl binary
+  --ovsdb-tool OVSDB_TOOL
+                        Path to the target ovsdb-tool binary
+  --ovsdb-server OVSDB_SERVER
+                        Path to the target ovsdb-server binary
+  --ovs-kmod OVS_KMOD   Path to the OVS kernel module
+  --ovs-src-dir OVS_SRC_DIR
+                        Directory for the OVS Source Files
+  --ovs-log-dir OVS_LOG_DIR
+                        Directory for the OVS Runtime Log Files
+  --ovs-version OVS_VERSION
+  --ovs-base-dir OVS_BASE_DIR
+                        OVS Base Installation Directory
+  --ovs-runtime-dir OVS_RUNTIME_DIR
+                        OVS Runtime Directory
+  --ovs-db-sock OVS_DB_SOCK
+                        Domain Socket Location
+  --ovs-db-file OVS_DB_FILE
+                        Location for the OVS database file
+  --dry                 Dry run only. Don't actually do anything
+  --log                 Enable logging
+  --verbose             Enable verbose output information
+  --kill                Kill running OVS
+  --keep-veths          By default, all existing veths will be destroyed and
+                        the veth module removed before initializing. If you
+                        don't want the veth module removed, specify this
+                        argument. Your mileage may vary if you use this.
+  --no-kmod             Do not attempt to insert or remove the OVS kernel
+                        module. Your mileage may vary.
+  --vlog                Tail the running vswitch.log file in a new xterm
+  -p PORT_COUNT, --port-count PORT_COUNT
+                        Number of veth ports to connect.
+  --bridge BRIDGE       Name of OF OVS Bridge
+  --cip CIP             Controller Connection
+  --cport CPORT         Controller Port
+  --max_backoff MAX_BACKOFF
+                        VSwitchD max backoff value
+  --keep-db             By default, a new database is initialized at each
+                        execution. If you want to keep and use the old
+                        database (if it exists), use this option
+
+
+
+
+-------------------------------------------------------------------------------
+TODO
+-------------------------------------------------------------------------------
+
+1. Better documentation. 
+2. Option for automatic downloading, configuration, and installation of OVS. 
+3. Symlinks or alias generation for selecting the correct ovs-* tools for
+   debugging the running configuration. 
+
+
+
+
diff --git a/Fabric/Utilities/tools/ovs-ctl/ovs-ctl-default.example.conf b/Fabric/Utilities/tools/ovs-ctl/ovs-ctl-default.example.conf
new file mode 100644
index 0000000..2996dce
--- /dev/null
+++ b/Fabric/Utilities/tools/ovs-ctl/ovs-ctl-default.example.conf
@@ -0,0 +1,96 @@
+###############################################################################
+#
+# This is the example/default ovs-ctl config file. 
+#
+# ovs-ctl config files will be searched and read, by default, int he following
+# order:
+#
+# /opt/ovs/ovs-ctl-default.conf
+# ~/.ovs-ctl
+#
+# This behavior can be modified and change specifically on the command line:
+#
+# Change the location of the default config file:
+# > ovs-ctl --default-config-file=/path/to/file
+#
+# Disable the default config file:
+# > ovs-ctl --no-default 
+#
+# Read these specific config files:
+# > ovs-ctl --config-file file1 file2 file3
+#
+# Note: The default config file reading behavior is equivalent to:
+#
+# > ovs-ctl --default /opt/ovs/ovs-ctl-default.conf --config-file ~/.ovs-ctl
+# 
+# This is also equivalent to:
+# > ovs-ctl --no-default --config-file /opt/ovs/ovs-ctl-default.conf ~/.ovs-ctl
+#
+#
+###############################################################################
+
+#
+# Default options can be specified here
+#
+[Defaults]
+# Default all configurations to 1.4.0
+config:1.4.0
+
+#
+# Specific OVS configurations go here
+#
+[1.4.0]
+# ovs-1.4.0, configured and built into /opt/ovs/1.4.0
+# Can be selected with 'ovs-ctl.py --config 1.4.0'
+ovs_src_dir:/opt/ovs/src/openvswitch-1.4.0
+ovs_base_dir:/opt/ovs/1.4.0
+ovs_runtime_dir:/var/run/ovs/1.4.0
+
+
+[1.3.0]
+# ovs-1.3.0, configured and built into /opt/ovs/1.3.0
+# Can be selected with 'ovsctl.py --config 1.3.0'
+ovs_src_dir:/opt/ovs/src/openvswitch-1.3.0
+ovs_base_dir:/opt/ovs/1.3.0
+ovs_runtime_dir:/var/run/ovs/1.3.0
+
+[1.2.2]
+# ovs-1.2.2, configured and built into /opt/ovs/1.2.2
+# Can be selected with 'ovsctl.py --config 1.2.2'
+ovs_src_dir:/opt/ovs/src/openvswitch-1.2.2
+ovs_base_dir:/opt/ovs/1.2.2
+ovs_runtime_dir:/var/run/ovs/1.2.2
+
+#
+# In the above configurations, the locations of the tools
+# are derived by ovs-ctl relative to 'ovs_src_dir' and 'ovs_base_dir'
+#
+# Individual tools and locations can be specified directly in 
+# the configuration (as well as the command line):
+#
+# Try:
+# 'ovs-ctl.py --no-default --config-file ovs-ctl-default.example.conf --config MyExample'
+#
+# In general, every command line option can be specified in a config file section. 
+#
+# The precedence of options is:
+#     1. Command Line Options
+#     2. [The Config You Specified]
+#     3. [The Defaults sections]
+#
+
+[MyExampleConfig]
+ovs_vswitchd_schema:/path/to/vswitch/schema/file
+ovs_vswitchdL:/path/to/vswitchd
+ovs_vsctl:/path/to/vsctl
+ovs_ofctl:/path/to/ofctl
+ovsdb_tool:/path/to/ovsdb_tool
+ovsd_db_file:/path/to/ovs_db_file
+ovs_db_sock:/path/to/ovs_db_sock
+ovs_kmod:/path/to/ovs_kmod
+
+
+
+
+
+
diff --git a/Fabric/Utilities/tools/ovs-ctl/ovs-ctl.py b/Fabric/Utilities/tools/ovs-ctl/ovs-ctl.py
new file mode 100755
index 0000000..13e287e
--- /dev/null
+++ b/Fabric/Utilities/tools/ovs-ctl/ovs-ctl.py
@@ -0,0 +1,542 @@
+
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+#!/usr/bin/python
+
+import os
+import subprocess
+import argparse
+import sys
+import signal
+import time
+import ConfigParser
+import pprint
+
+###############################################################################
+#
+# Arguments
+#
+# Arguments can be specified directly, or via config file. 
+# TODO -- Make this a separate reusable class
+#
+################################################################################
+gBasename = "ovs-ctl"
+
+gConfigParser = argparse.ArgumentParser(description=gBasename, add_help=False)
+
+gConfigParser.add_argument('-cf', '--config-file', 
+                     help="Load settings from the given config file", 
+                     nargs='+', metavar="FILE", 
+                     default=os.path.expanduser("~/."+gBasename))
+
+gConfigParser.add_argument('-c', '--config', 
+                     help="Use the specified configuration section", 
+                     default=None)
+
+gConfigParser.add_argument('-d', '--default-config-file', 
+                     help="Location of the local default config file", 
+                     metavar="FILE", 
+                     default="/opt/ovs/%s-default.conf" % (gBasename))
+
+gConfigParser.add_argument('-nd', '--no-default', 
+                     help="Do not load the default config file", 
+                     action='store_true', default=False)
+gConfigParser.add_argument('--dump-config',
+                     help="Dump the loaded configuration settings", 
+                     action='store_true', default=False)
+
+#
+# Parse the config files first, then parse remaining command line arguments
+#
+gConfig = ConfigParser.SafeConfigParser()
+configArgs, remainingArgs = gConfigParser.parse_known_args()
+
+if not configArgs.no_default:
+    gConfig.read([configArgs.default_config_file])
+
+if isinstance(configArgs.config_file, str):
+    configFiles = [ configArgs.config_file]
+else:
+    configFiles = configArgs.config_file
+
+configFiles = [ os.path.expanduser(x) if x.startswith('~') else x 
+                for x in configFiles ]
+
+gConfig.read(configFiles)
+
+# Dump loaded config if requested
+if configArgs.dump_config:
+    for section in gConfig.sections():
+        print section
+        for option in gConfig.options(section):
+            print " ", option, "=", gConfig.get(section, option)
+    sys.exit()
+
+
+
+#
+# Functional arguments go here
+#
+
+#
+# OVS target binaries -- these can all be specified individually. 
+# If not specified, they are determined by the base directory settings
+#
+gParser = argparse.ArgumentParser(parents=[gConfigParser])
+
+gParser.add_argument('--ovs-vswitchd-schema', 
+                     help="""Path to the vswitchd.ovsschema file""")
+gParser.add_argument('--ovs-vswitchd-log', 
+                     help="""Path to the vswitchd log file""")
+gParser.add_argument('--ovs-vswitchd-verbosity', 
+                     help="""Set vswitchd logging level (off/emer/err/warn/info/dbg)""",
+                     default="dbg")
+gParser.add_argument('--ovs-vswitchd', 
+                     help="""Path to the target ovs-vswitchd binary""")
+gParser.add_argument('--ovs-vsctl', 
+                     help="""Path to the target ovs-vsctl binary""")
+gParser.add_argument('--ovs-ofctl', 
+                     help="""Path to the target ovs-ofctl binary""")
+gParser.add_argument('--ovsdb-tool', 
+                     help="""Path to the target ovsdb-tool binary""")
+gParser.add_argument('--ovsdb-server', 
+                     help="""Path to the target ovsdb-server binary""")
+gParser.add_argument('--ovs-kmod', 
+                     help="""Path to the OVS kernel module""")
+gParser.add_argument('--ovs-src-dir',
+                     help="""Directory for the OVS Source Files""")
+
+gParser.add_argument('--ovs-log-dir',
+                     help="""Directory for the OVS Runtime Log Files""")
+
+gParser.add_argument('--ovs-version')
+
+gParser.add_argument("--ovs-base-dir", help="OVS Base Installation Directory")
+
+gParser.add_argument("--ovs-runtime-dir", 
+                     help="OVS Runtime Directory", 
+                     default="/var/run/ovs")
+
+gParser.add_argument('--ovs-db-sock', 
+                     help="Domain Socket Location")
+                     
+gParser.add_argument('--ovs-db-file', 
+                     help="Location for the OVS database file")
+
+
+#
+# Logging/Debugging/Testing options
+#
+gParser.add_argument('--dry', 
+                     help="""Dry run only. Don't actually do anything""", 
+                     action='store_true',  default=False)
+
+gParser.add_argument('--log', 
+                     help='Enable logging', 
+                     action='store_true', default=False)
+
+gParser.add_argument('--verbose', 
+                     help='Enable verbose output information', 
+                     action='store_true', default=False)
+
+gParser.add_argument("--kill", help="Kill running OVS", 
+                     default=False, action='store_true')
+
+gParser.add_argument("--keep-veths", 
+                     help="""By default, all existing veths will be destroyed and
+the veth module removed before initializing. If you don't want the veth module
+removed, specify this argument. Your mileage may vary if you use this.""", 
+                     default=False, action='store_true')
+
+gParser.add_argument("--no-kmod", 
+                     help="""Do not attempt to insert or remove the OVS kernel module. 
+Your mileage may vary.""", 
+                     default=False, action='store_true')
+
+gParser.add_argument("--vlog", 
+                     help="""Tail the running vswitch.log file in a new xterm""", 
+                     default=False, action='store_true')
+
+#
+# Runtime and setup arguments
+#
+gParser.add_argument('-p', '--port-count', type=int, 
+                     help="Number of veth ports to connect.", 
+                     default='4')
+
+
+gParser.add_argument("--bridge", help="Name of OF OVS Bridge", 
+                     default="ofbr0")
+
+gParser.add_argument("--cip", help="Controller Connection", 
+                     default="127.0.0.1")
+
+gParser.add_argument("--cport", type=int, help="Controller Port", 
+                     default=6653)
+gParser.add_argument("--dpid", help="DPID")
+
+gParser.add_argument("--max_backoff", help="VSwitchD max backoff value", 
+                     default=1000, type=int)
+
+
+gParser.add_argument("--keep-db", 
+                     help="""By default, a new database is initialized at each
+execution. If you want to keep and use the old database (if it exists), 
+use this option""", 
+                     action='store_true', default=False)
+
+gParser.add_argument('-lb', '--loopback',
+                     help="Create a loopback pair.  The port numbers are port_count+1 and port_count+2.", 
+                     default=False, action='store_true')
+
+
+gParser.add_argument("--cli", 
+                     help="Run the ovs-ctl cli after initialization", 
+                     action='store_true', default=False)
+
+gParser.add_argument("--teardown", 
+                     help="Kill OVS instance after CLI exits", 
+                     action='store_true', default=False)
+
+#
+# Reset defaults based on config files and override
+#
+# Anything in the "Defaults" section gets slurped first:
+defaults = {}
+if gConfig.has_section('Defaults'):
+    defaults = dict(gConfig.items('Defaults'))
+    gParser.set_defaults(**defaults)
+
+#
+# The configuration to execute might be specified in on the command line, or in the Defaults section(s)
+# of the config files. 
+#
+# If its specified on the command line, it will be present in configArgs.config
+# If its specified in the section, it will only be present in the defaults dict. 
+# Need to check both. Command line takes precedence. 
+#
+gConfigSection = None
+if configArgs.config != None:
+    gConfigSection = configArgs.config
+elif defaults.has_key('config'):
+    gConfigSection = defaults['config']
+
+
+if gConfigSection != None:
+    if gConfig.has_section(gConfigSection):
+        section = dict(gConfig.items(gConfigSection))
+        gParser.set_defaults(**section)
+    else:
+        print >>sys.stderr, "Requestion configuration '%s' does not exist" % (configArgs.config)
+        sys.exit()
+
+
+###############################################################################
+# 
+# Done with argument setup. Parser remaining arguments
+#
+###############################################################################
+gArgs = gParser.parse_args(remainingArgs)
+
+
+#
+# At the end of all of this, we need the following things to be defined
+# or derived:
+#
+gRequiredOptions = [
+    [ 'ovs_vswitchd_schema', 'ovs_src_dir',     '/vswitchd/vswitch.ovsschema', True,  True  ], 
+    [ 'ovs_vswitchd',        'ovs_base_dir',    '/sbin/ovs-vswitchd',          True,  True  ], 
+    [ 'ovs_vsctl',           'ovs_base_dir',    '/bin/ovs-vsctl',              True,  True  ], 
+    [ 'ovs_ofctl',           'ovs_base_dir',    '/bin/ovs-ofctl',              True,  True  ], 
+    [ 'ovsdb_tool',          'ovs_base_dir',    '/bin/ovsdb-tool',             True,  True, ], 
+    [ 'ovsdb_server',        'ovs_base_dir',    '/sbin/ovsdb-server',          True,  True, ], 
+    [ 'ovs_db_file',          'ovs_base_dir',    '/ovs.db',                    False, True, ], 
+    [ 'ovs_db_sock',         'ovs_runtime_dir', '/db.sock',                    False, True, ], 
+    [ 'ovs_kmod',            'ovs_base_dir',    '/sbin/openvswitch_mod.ko',    True,  not gArgs.no_kmod ], 
+]
+
+def __require_option(key, basedir, path, exists=True):
+    value = getattr(gArgs, key)
+    if value is None:
+        # Unspecified -- try to default based on given path
+        value = getattr(gArgs, basedir)
+
+        if value is None:
+            return False
+
+        value += path
+
+    if exists and not os.path.exists(value):
+        return False
+
+    if gArgs.verbose:
+        print '--v-- option: %s @ %s' % (key, value)
+
+    setattr(gArgs, key, value)
+
+
+Validated = True
+# Try to validate as many things as we can
+for option in gRequiredOptions:
+    if option[4]:
+        if __require_option(option[0], option[1], option[2], option[3]) == False:
+            Validated = False
+
+# If any of them failed, try to be as helpful as possible
+if Validated == False:
+    print >>sys.stdout, "\nConfiguration problem. One or more required settings are missing or could not be derived:\n"
+    for option in gRequiredOptions:
+        if option[4] is False:
+            continue
+
+        value = getattr(gArgs, option[0])
+        if value:
+            print >>sys.stdout, " %s: %s" % (option[0], value), 
+            if option[3] and not os.path.exists(value):
+                print >>sys.stdout, "-- does not exist"
+            else:
+                print "(OK)"
+        else:
+            print >>sys.stdout, " %s: Unknown. " % (option[0]), 
+            base = getattr(gArgs, option[1])
+            if base:
+                print >>sys.stdout, "Search path was '%s'." % (base + option[2])
+            else:
+                print >>sys.stdout, "Could not derive path because '%s' was also unspecified." % (option[1])
+    print >>sys.stdout
+    sys.exit()
+
+
+
+
+#
+# If we aren't in a dry run, you must execute as root to accompish anything
+#
+if not os.geteuid() == 0 and gArgs.dry == False:
+    print >>sys.stderr, "Must run as root to accomplish any of this."
+    sys.exit()
+
+
+###############################################################################
+#
+# Helpers 
+#
+###############################################################################
+
+def createVeths(count):
+    for idx in range(0, count):
+        lcall(["/sbin/ip", "link", "add", "type", "veth"])
+
+def vethsUp(count):
+    for idx in range(0, count*2):
+        lcall(["/sbin/ifconfig", 'veth%s' % (idx), "up"])
+
+def lcall(cmd, log=gArgs.log, dry=gArgs.dry, popen=False, 
+          pidFile=None):
+    
+    if log or gArgs.verbose:
+        print "%s: %s" % ('popen' if popen else 'call', cmd)
+    
+    if not dry:
+        if not popen:
+            subprocess.call(cmd)
+        else:
+            p = subprocess.Popen(cmd)
+            if pidFile != None:
+                pidf = open(pidFile, "w"); 
+                print >>pidf, p.pid
+                pidf.close()
+
+    
+
+def vsctl(argsList):
+    argsList.insert(0, "--db=unix:%s" % (gArgs.ovs_db_sock))
+    argsList.insert(0, gArgs.ovs_vsctl)
+    lcall(argsList)
+
+def ofctl(argsList):
+    argsList.insert(0, gArgs.ovs_ofctl)
+    lcall(argsList)
+
+def killpid(pid):
+    try:
+        os.kill(pid, signal.SIGTERM)
+        return False
+    except OSError, e:
+        return True
+
+
+def killp(pidfile):
+    if os.path.exists(pidfile):
+        pid=int(open(pidfile).read())
+        print "Killing %s, pid=%s..." % (pidfile, pid),
+        if not gArgs.dry:
+            while not killpid(pid):
+                time.sleep(1)
+                pass
+        print "dead"
+
+
+###############################################################################
+#
+# main
+#
+###############################################################################
+
+gServerPid = gArgs.ovs_runtime_dir + "/ovsdb-server.pid"
+gSwitchPid = gArgs.ovs_runtime_dir + "/ovs-vswitchd.pid"
+gLogPid=     gArgs.ovs_runtime_dir + "/ovs-vswitchd-tail.pid"
+
+# Kill previous execution based on contents of the runtime dir
+if os.path.exists(gServerPid):
+    print gServerPid
+    vsctl(["del-br", gArgs.bridge])
+
+
+def killall():
+    # Kill existing DB/vswitchd
+    killp(gSwitchPid)
+    killp(gServerPid)
+    killp(gLogPid)
+
+    # Remove old logpid file, since this does not happen automagically
+    if os.path.exists(gLogPid):
+        os.remove(gLogPid)
+
+    if gArgs.keep_veths == False:
+        lcall(['/sbin/rmmod', 'veth'])
+        lcall(['/sbin/modprobe', 'veth'])
+
+    # Remove kmod
+    lcall(['/sbin/rmmod', gArgs.ovs_kmod])
+
+
+killall()
+if gArgs.kill == True:
+    # Don't do anything else
+    sys.exit()
+
+
+# Remove bridge module
+lcall(['/sbin/rmmod', 'bridge'])
+# Insert openvswitch module
+lcall(['/sbin/insmod', gArgs.ovs_kmod])
+
+port_count = gArgs.port_count
+if gArgs.loopback:
+    port_count += 1
+createVeths(port_count)
+vethsUp(port_count)
+
+if not os.path.exists(gArgs.ovs_db_file) or gArgs.keep_db == False:
+    print "Initializing DB @ %s" % (gArgs.ovs_db_file)
+    if os.path.exists(gArgs.ovs_db_file) and not gArgs.dry:
+        os.remove(gArgs.ovs_db_file)
+
+    lcall([gArgs.ovsdb_tool, "create", gArgs.ovs_db_file, 
+           gArgs.ovs_vswitchd_schema])
+else:
+    print "Keeping existing DB @ %s" % (gArgs.ovs_db_file)
+
+
+if not os.path.exists(gArgs.ovs_runtime_dir):
+    os.makedirs(gArgs.ovs_runtime_dir)
+
+# Start dbserver
+lcall([gArgs.ovsdb_server, gArgs.ovs_db_file, 
+       "--remote=punix:%s" % (gArgs.ovs_db_sock), 
+       "--detach", "--pidfile=%s" % (gServerPid)])
+
+# Init db
+vsctl(["--no-wait", "init"])
+
+# Start vswitchd
+startV = [ gArgs.ovs_vswitchd, 
+          "unix:%s" % (gArgs.ovs_db_sock), 
+          "--verbose=%s" % gArgs.ovs_vswitchd_verbosity,
+          "--detach",
+          "--pidfile=%s" % (gSwitchPid) ]
+
+if gArgs.ovs_vswitchd_log:
+    startV.append("--log-file=%s" % (gArgs.ovs_vswitchd_log))
+
+lcall(startV)
+
+if gArgs.vlog:
+    lcall(["xterm", "-T", "vswitchd-log", "-e", "tail", "-f", 
+           gArgs.ovs_vswitchd_log], 
+          popen=True, pidFile=gLogPid)
+
+
+# Add a bridge
+vsctl(["add-br", gArgs.bridge])
+ofctl(["show", gArgs.bridge])
+
+# Add Veths to bridge
+for idx in range(0, gArgs.port_count):
+    vsctl(["add-port", gArgs.bridge, "veth%s" % (idx*2)])
+
+# Check if loopback port added
+if gArgs.loopback:
+    lb_idx = gArgs.port_count * 2
+    vsctl(["add-port", gArgs.bridge, "veth%d" % (lb_idx)])
+    vsctl(["add-port", gArgs.bridge, "veth%d" % (lb_idx+1)])
+
+if gArgs.dpid:
+    vsctl(["set", "bridge", gArgs.bridge, "other-config:datapath-id=%s" % (
+                gArgs.dpid)])
+
+# Set controller
+vsctl(["set-controller", gArgs.bridge, "tcp:%s:%s" % (
+        gArgs.cip, gArgs.cport)])
+
+# Minimize default backoff for controller connections
+vsctl(["set", "Controller", gArgs.bridge, 
+       "max_backoff=%s" % (gArgs.max_backoff)])
+
+
+ofctl(["show", gArgs.bridge])
+
+
+if gArgs.cli:
+    while True:
+        cmd = raw_input("[%s] ovs-ctl> " % gConfigSection)
+        if cmd and cmd != "":
+            args = cmd.split(" ")
+            if args[0] == "vsctl" or args[0] == "ovs-vsctl":
+                vsctl(args[1:])
+            elif args[0] == "ofctl" or args[0] == "ovs-ofctl":
+                ofctl(args[1:])
+            elif args[0] == "dumpflows" or args[0] == "flowtable":
+                ofctl(["dump-flows", "%s" % gArgs.bridge])
+            elif args[0] == "exit" or args[0] == "quit":
+                break; 
+            elif args[0] == "kill":
+                gArgs.teardown = True
+                break
+            else:
+                print "unknown command '%s'" % args[0]
+            
+
+if gArgs.teardown:
+    print "Killing OVS"
+    killall()
+
+
+
+
+                        
+