VOL-1097 : Ofagent integration for voltha 2.0

- Created a common location for python based components
- Adjusted the ofagent component to interact with voltha 2.0
- Added streaming rpc methods for rcv/send of packets to voltha api
- Adjusted voltha.proto

Change-Id: I47fb7b80878ead060b4b42bd16cb4f8aa384fdb6
diff --git a/python/ofagent/loxi/of11/__init__.py b/python/ofagent/loxi/of11/__init__.py
new file mode 100644
index 0000000..29d4afe
--- /dev/null
+++ b/python/ofagent/loxi/of11/__init__.py
@@ -0,0 +1,29 @@
+# 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/python/ofagent/loxi/of11/action.py b/python/ofagent/loxi/of11/action.py
new file mode 100644
index 0000000..79fc2ff
--- /dev/null
+++ b/python/ofagent/loxi/of11/action.py
@@ -0,0 +1,1675 @@
+# 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/python/ofagent/loxi/of11/common.py b/python/ofagent/loxi/of11/common.py
new file mode 100644
index 0000000..dadd6bc
--- /dev/null
+++ b/python/ofagent/loxi/of11/common.py
@@ -0,0 +1,1744 @@
+# 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/python/ofagent/loxi/of11/const.py b/python/ofagent/loxi/of11/const.py
new file mode 100644
index 0000000..9705d89
--- /dev/null
+++ b/python/ofagent/loxi/of11/const.py
@@ -0,0 +1,733 @@
+# 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/python/ofagent/loxi/of11/instruction.py b/python/ofagent/loxi/of11/instruction.py
new file mode 100644
index 0000000..7910aef
--- /dev/null
+++ b/python/ofagent/loxi/of11/instruction.py
@@ -0,0 +1,386 @@
+# 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/python/ofagent/loxi/of11/message.py b/python/ofagent/loxi/of11/message.py
new file mode 100644
index 0000000..cb102f8
--- /dev/null
+++ b/python/ofagent/loxi/of11/message.py
@@ -0,0 +1,7856 @@
+# 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/python/ofagent/loxi/of11/util.py b/python/ofagent/loxi/of11/util.py
new file mode 100644
index 0000000..f5dd743
--- /dev/null
+++ b/python/ofagent/loxi/of11/util.py
@@ -0,0 +1,140 @@
+# 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